2016-11-24 4 views
1

Ich lese Effektive Java 2nd Edition von Joshua Bloch.Was bedeutet der genaue Rückgabewert ihres hashCodes?

In diesem Absatz erwähnt er, dass:

Viele Klassen in der Java-Plattform-Bibliotheken, wie String, Integer und Datum, in ihren Spezifikationen umfassen den genauen Wert durch ihre hashCode Methode als Funktion zurückgegeben des Instanzwerts. Dies ist im Allgemeinen keine gute Idee, da es Ihre Fähigkeit einschränkt, die Hash-Funktion in zukünftigen Versionen zu verbessern. Wenn Sie die Details einer Hash-Funktion nicht näher angeben und ein Fehler gefunden oder eine bessere Hash-Funktion gefunden wird, können Sie die Hash-Funktion in einer späteren Version ändern, ohne dass die Clients von den genauen Werten der Hash-Funktion abhängig sind.

Kann jemand bitte einige Einblicke teilen, was er mit "genauen" Werten meint. Ich habe mir die String-Implementierungsklasse angeschaut, konnte aber immer noch nicht verstehen, was er damit meint ...

Vielen Dank im Voraus!

+3

Dies bedeutet, dass der von 'hashCode()' zurückgegebene Wert im Javadoc angegeben ist. z.B. [siehe 'String.hashCode()'] (http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#hashCode()): Dort gibt es eine Formel zur Berechnung der zurückgegebener Wert –

+0

Er meinte wahrscheinlich so etwas wie: 's [0] * 31^(n-1) + s [1] * 31^(n-2) + ... + s [n-1]', das ist die Algorithmus, der im [Javadoc] (http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#hashCode%28%29) für 'java.lang.String # hashCode' angekündigt wurde . – Mena

+0

In 'java.lang.Integer' ist es einfach" gleich dem primitiven int-Wert, der von diesem Integer-Objekt dargestellt wird. " - siehe [hier] (https://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html#hashCode%28%29). – Mena

Antwort

6

Von String.hashCode():

Gibt einen Hash-Code für diese Zeichenfolge. Der Hash-Code für ein String-Objekt wird als

berechnet
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1] 

Indem ich die Definition in der Javadoc-, Menschen Code schreiben können, die genau an diesem hängt Hashing-Algorithmus. Das Ändern des Hash-Algorithmus in einer zukünftigen Version würde diesen Code dann brechen.

+4

Wenn man es im Javadoc aufschreibt, wird es Teil des Vertrags für die Klasse, so dass es sogar richtig ist, Code in Abhängigkeit von diesem Algorithmus zu schreiben. –

+0

@ piet.t Richtig, aber nicht sehr weise. :) – biziclop

+1

@biziclop die weniger weise Bewegung ist, die Formel in der Javadoc an erster Stelle anzugeben. Ich bin mir sicher, dass sie ihre Gründe hatten, aber ... –

2

Dies bedeutet, dass der von hashCode() zurückgegebene Wert im Javadoc vorgeschrieben ist.

z.B.

  • String.hashCode():

    Gibt einen Hash-Code für diese Zeichenfolge. Der Hash-Code für ein String-Objekt wird berechnet als

    s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1] 
    
  • Integer.hashCode():

    [Returns] ein Hash-Code-Wert für dieses Objekt, die gleich den primitiven int Wert dieses Integer-Objekt dargestellt .

  • Date.hashCode():

    Gibt einen Hash-Code-Wert für dieses Objekt. Das Ergebnis ist das exklusive OR der beiden Hälften des von der Methode getTime() zurückgegebenen primitiven langen Werts.Das heißt, der Hash-Code der Wert des Ausdrucks ist:

    (int)(this.getTime()^(this.getTime() >>> 32)) 
    
2

Wenn Sie bei der API-Dokumentation von java.lang.String.hashCode() aussehen, es beschreibt genau, wie das Verfahren durchgeführt wird:

Gibt einen Hash-Code für diese Zeichenfolge zurück. Der Hash-Code für ein String-Objekt wird als

berechnet
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1] 

Verwendung int Arithmetik, wobei S [i] sind die i-te Zeichen des Strings, n die Länge der Zeichenfolge, und^zeigt Exponentiation. (Der Hash-Wert des leeren String ist null.)

Was Bloch sagt, ist, dass es ein Fehler ist, dass Klassen wie String die Implementierungsdetails in der API-Dokumentation beschreiben, weil dies bedeutet, dass Programmierer verlassen können Die Methode wird auf diese Weise implementiert. Wenn Oracle in einer zukünftigen Java-Version einen anderen, möglicherweise effizienteren Algorithmus implementieren möchte, um einen Hash-Code für eine Zeichenfolge zu berechnen, wäre dies ein Abwärtskompatibilitätsproblem - das Verhalten könnte sich im Vergleich zu früheren Java-Versionen ändern.

Durch die detaillierte Beschreibung der Implementierung in der API-Dokumentation wurde die Art der Implementierung in die offizielle Spezifikation der Java-API übernommen.

Im Allgemeinen sollte die API-Dokumentation nur beschreiben, was der Zweck der Methode ist und nicht genau, wie sie implementiert ist.