Meine Hausaufgaben...

  • Themenstarter Themenstarter Beni
  • Beginndatum Beginndatum
Status
Nicht offen für weitere Antworten.
B

Beni

Gast
... bitte lösen :bae:

Ne, ernsthaft. Da bei uns tatsächlich eine Frage über Java kommt (ein Ereignis, das gewürdigt werden muss. Wir lernen eine jahrzente alte Sprache, Eiffel...), will ich doch mal die Community damit beglücken. :wink: (P.S. es geht um Hashtables)

In der Programmiersprache Java hat die Klasse Object, die Methode "hashCode", welches die Adresse, an der das Objekt gespeichert ist, als int zurückgibt.

a) was für Vorteile hat diese Implementation
b) Kann man diese Implementation für alle Klassen benutzen?


Meine Überlegungen führten mal zu:

a)
- Jedes Object kann als Schlüssel verwendet werden.
- Der Schlüssel wird ziemlich zufällig gewählt.
- Die Methode ist schnell

b)
- Vom Standpunkt der Vererbung: ja
- Vom Standpunkt der Definition einer Hashfunktion: nein. Verschiedene Instanzen von Objekten mit gleichem Inhalt müssten denselben Schlüssel generieren, tun sie aber nicht. Das Problem kann nur durch überschreiben von hashCode gelöst werden.

Befindet sich hier ein Datenbank-Spezialist? :wink:

mfg Beni
 
weiteres Problem:

nutzt du zum beispiel eine collection als key eine hashtabelle und fügst dieser collection objekte hinzu, so ändert sich auch ihr hashcode - ist zwar logisch, aber nicht unbedingt immer vorteilhaft
 
Die Methode hashCode gibt nicht (unbedingt) die Adresse im Speicher wieder. Das wäre in Java sicher auch nicht sinnvoll. Dieser Hash-Code berechnet sich aus den Werten der Eigenschaften des Objektes. Eine Möglichkeit, die Methode zu implementieren, findest Du im Effektiv Java programmieren von Joshua Bloch. Da aber die Klasse Object keine Eigenschaften besitzt, wird irgendein Hash-Code berechnet.
 
@nollario
Thx, an das hab ich nicht gedacht

@Grizzly
Die Methode hashCode gibt nicht (unbedingt) die Adresse im Speicher wieder. Das wäre in Java sicher auch nicht sinnvoll
Eigentlich geht es nur darum, dass das so in der Aufgabe steht. Aber egal, beziehst du dich jetzt auf Object#hashCode oder auf alle hashCode Implementationen.

Wieso sollte es nicht sinnvoll sein, die Speicheradresse zu verwenden? Die Variante ist doch ziemlich praktisch. (Oder missverstehe ich dich. Das ein String eine eigene Implementation braucht, ist mir schon klar...).

mfg Beni
 
Beni hat gesagt.:
Wieso sollte es nicht sinnvoll sein, die Speicheradresse zu verwenden? Die Variante ist doch ziemlich praktisch. (Oder missverstehe ich dich. Das ein String eine eigene Implementation braucht, ist mir schon klar...).

Wenn du z.B. Objekte in einer Hashmap mit einem String als Key ablegst, möchtest du doch eigentlich nicht immer das selbe String-Objekt nehmen müssen, um einen Wert auszulesen, sondern einen String, der denselben Hashcode hat, wie der mit dem du es abgelegt hast.
 
hashCode sollte bei gleichen Eigenschaften auch den gleichen Wert liefen. hashCode verhält sich in dem Fall wie equals und nicht wie == .
 
Beni hat gesagt.:
(Oder missverstehe ich dich. Das ein String eine eigene Implementation braucht, ist mir schon klar...).

Pulvertoastman hat gesagt.:
nicht immer das selbe String-Objekt nehmen müssen

Hier sprechen glaub alle vom selben, aber niemand liest die anderen Posts. :lol:

mfg Beni, der solche Missverständnisse lustig findet.
 
Nein. String war anscheinend ein schlecht gewähltes Beispiel. Du kannst dafür auch zum Beispiel java.lang.Integer oder jede beliebige andere von dir geschriebene Klasse einsetzen.

Warum sollte String da auch ein Sonderfall sein?

Wichtig ist dabei halt, dass wie schon gesagt wurde, dass die Eigenschaften eines Objektes zählen und nicht die Speicheradresse.
 
:idea: Jetzt verstehe ich, was Du sagen wolltest.

Ja, das stimmt schon, was Du da schreibst.

Von diesem Standpunkt aus, kann man wohl sagen, ein Interface "Hashable" wäre sinnvoller (bzw, es würde zumindest keine Nachteile geben, da man die Methode sowieso in den meisten Fällen überschreiben muss).

mfg Beni
 
Pulvertoastman hat gesagt.:
Nein. String war anscheinend ein schlecht gewähltes Beispiel. Du kannst dafür auch zum Beispiel java.lang.Integer oder jede beliebige andere von dir geschriebene Klasse einsetzen.

Warum sollte String da auch ein Sonderfall sein?

Wichtig ist dabei halt, dass wie schon gesagt wurde, dass die Eigenschaften eines Objektes zählen und nicht die Speicheradresse.

Meines erachtens errechnet sicher der Hashcode nicht aus den Eigenschaften sondern aus einer interenen Adresse, so dass unterschiedliche Object mit gleichen Eigenschaften auch unterschiedliche Hashwerte aufweisen.

z.B.
Code:
JButton b1 = new JButton("test");
JButton b2 = new JButton("test");
Sysem.out.print(b1.equals(b2)?"wahr":"falsch");

Die Eigenschaften sind zwar gleich aber die Ausgabe ist 'falsch'.
Ein Sonderfall ist String hier wäre die Ausgabe 'wahr'.

Es ist auch so, dass Objekte(auch Strings) mit gleichen Eigenschaften, die aber in unterschiedlichen Anwendungen laufen, einen unterschiedlichen Hashcode aufweisen.
 
stevg hat gesagt.:
[...]
Meines erachtens errechnet sicher der Hashcode nicht aus den Eigenschaften sondern aus einer interenen Adresse, so dass unterschiedliche Object mit gleichen Eigenschaften auch unterschiedliche Hashwerte aufweisen.
[...]
Es ist auch so, dass Objekte(auch Strings) mit gleichen Eigenschaften, die aber in unterschiedlichen Anwendungen laufen, einen unterschiedlichen Hashcode aufweisen.

Der HashCode der Methode hashCode der Klasse Object benutzt auch irgend etwas anderes. In Fall der Java VM des JDK SE 1.4.2 könnte es sogar eine Speicherangabe sein. Es wird aber empfohlen, die Methode hashCode sowie die Methode equals in allen Subklassen entsprechenden zu überschreiben.
 
Nur in der Standard-Api ist das zu min. 90% nicht der Fall, wieso?
 
stevg hat gesagt.:
Meines erachtens errechnet sicher der Hashcode nicht aus den Eigenschaften sondern aus einer interenen Adresse, so dass unterschiedliche Object mit gleichen Eigenschaften auch unterschiedliche Hashwerte aufweisen.

z.B.
Code:
JButton b1 = new JButton("test");
JButton b2 = new JButton("test");
Sysem.out.print(b1.equals(b2)?"wahr":"falsch");

Die Eigenschaften sind zwar gleich aber die Ausgabe ist 'falsch'.
Ein Sonderfall ist String hier wäre die Ausgabe 'wahr'.

Es ist auch so, dass Objekte(auch Strings) mit gleichen Eigenschaften, die aber in unterschiedlichen Anwendungen laufen, einen unterschiedlichen Hashcode aufweisen.

Nein, das ist so nicht ganz richtig. Die Forderung von hashCode ist, dass sie denselben Wert liefert, wenn zwei Objecte via equals gleich sind.

Ansonsten findet sich eine nette Beschreibung zum Hashcode und deren Berechenung auf
http://www.langer.camelot.de/Articles/JavaSpektrum/03.HashCode/03.HashCode.html
Dort wird auch eingehend auf die enge Beziehung zwischen Gleichheit und hashcode eingegangen.

Unter anderem findet sich auch die Lösung, warum JButtons mit dem gleichen Text nicht gleich sind (Man beachte: JButton erbt von Container):

Selbst wenn man alle oben geschilderten Probleme vermieden hat und hashCode() korrekt implementiert hat, gibt es immer noch Überraschungen und Fehlerquellen, die mit der Referenz-Semantik in Java zu tun haben. In Java enthalten alle Container des JDK, inklusiver der hash-basierten Container, grundsätzlich Referenzen auf Objekte und niemals Kopien der "enthaltenen" Objekte. Infolgedessen erfolgt der Zugriff auf Elemente, die in einem hash-basierten Container abgelegt sind, immer über Referenzen. Wenn diese Referenzen verwendet werden, um das referenzierte Objekt zu modifizieren, dann ist es wahrscheinlich, dass der hash-basierte Container zerstört wird.
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben