2012-06-06 6 views
5

Hier ist der Code Probe von Punkt 9:Erklärung Notwendigkeit hashcode Beispiel in Effective Java Lehrbuch

public final class PhoneNumber { 
    private final short areaCode; 
    private final short prefix; 
    private final short lineNumber; 

    @Override 
    public int hashCode() { 
    int result = 17; 
    result = 31 * result + areaCode; 
    result = 31 * result + prefix; 
    result = 31 * result + lineNumber; 
    return result; 
    } 
} 

Pg 48 Staaten: „der Wert 31 wurde gewählt, weil es sich um eine ungerade Primzahl ist Wäre es. selbst wenn die Multiplikation übergelaufen wäre, wäre die Information verloren, da die Multiplikation mit 2 der Verschiebung gleichkommt. "

Ich verstehe das Konzept der Multiplikation mit 2 entspricht Bitverschiebung. Ich weiß auch, dass wir immer noch einen Überlauf (daher Informationsverlust) bekommen werden, wenn wir eine große Zahl mit einer großen ungeraden Primzahl multiplizieren. Was ich nicht verstehe ist, warum Informationsverlust, der durch Multiplikation mit großen ungeraden Primzahlen entsteht, einem Informationsverlust vorzuziehen ist, der sich aus der Multiplikation mit großen geraden Zahlen ergibt.

+1

andere als 2, keine andere gerade Zahl ist prime –

+0

omg! Ich kann nicht glauben, dass ich das vergessen habe. Ich denke, ich hatte gerade einen Moment der Dummheit. Danke :) – Kes115

+3

Dies kann ein Duplikat von http://stackoverflow.com/questions/299304/why-does-javashashashcode-in-string-use-31-as-a-multiplier sein. –

Antwort

6

Bei einem geraden Multiplikator ist das niedrigstwertige Bit nach der Multiplikation immer Null. Bei einem ungeradzahligen Multiplikator ist das niedrigstwertige Bit entweder Eins oder Null, abhängig davon, was der vorherige Wert von result war. Daher verliert der gerade Multiplikator die Unsicherheit über das niedrige Bit, während der ungerade Multiplikator es bewahrt.

1

Es gibt nicht so etwas wie eine große sogar prime - die einzige gerade Primzahl ist 2.

das beiseite - die allgemeine Punkt eines mittleren prime # verwenden, anstatt einen kleinen wie 3 oder 5 um die Wahrscheinlichkeit zu minimieren, dass zwei Objekte mit dem gleichen Hash-Wert enden, Überlauf oder nicht.

Das Risiko des Überlaufs ist nicht das Problem an sich; Das eigentliche Problem ist, wie verteilt die Hashcode-Werte für die Menge der Objekte sind, die gehashed werden. Da Hash-Codes in Datenstrukturen wie HashSet, HashMap usw. verwendet werden, möchten Sie die Anzahl der Objekte minimieren, die möglicherweise denselben Hash-Code verwenden, um die Suchzeiten für diese Sammlungen zu optimieren.