[Read Effective Java] Kapitel 3 Punkt 9 "Wenn Sie equals überschreiben, überschreiben Sie immer hashCode"

Überschreiben Sie immer hashCode, wenn Sie equals überschreiben

Alle Klassen, die gleich überschreiben, brechen den allgemeinen Vertrag für Object.hashCode, sofern sie nicht auch hashCode überschreiben.

Beispielcode

Der folgende Code überschreibt gleich hashCode wird nicht überschrieben

Beispiel 1


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

    public PhoneNumber(int areaCode, int prefix,
                       int lineNumber){
        rangeCheck(areaCode, 999, "area code");
        rangeCheck(prefix, 999, "prefix");
        rangeCheck(lineNumber, 9999, "line number");
        this.areaCode = (short)areaCode;
        this.prefix = (short)prefix;
        this.lineNumber = (short)lineNumber;
    }

    private static void rangeCheck(int arg, int max, 
                                   String name){
        if (arg < 0 || arg > max)
            throw new IllegalArgumentException(name +": " + arg);
    }

    @Override public boolean equals(Object o){
        if (o == this)
            return true;
        if (!(o instanceof PhoneNumber))
            return false;
        PhoneNumber pn = (PhoneNumber)o;
        return pn.lineNumber == lineNumber
            && pn.prefix == prefix
            && pn.areaCode == areaCode;
    }

    //unvollständig-Es gibt keine hashCode-Methode!
    
    ... //Der Rest entfällt
}

Angenommen, Beispiel 1 wird in HashMap verwendet. In Beispiel 2 wird erwartet, dass "m.get (neue Telefonnummer (707, 867, 5309)" "Jenny" zurückgibt, aber "null" zurückgibt. Da wir hashCode nicht überschrieben haben, haben put put PhoneNumber und get PhoneNumber unterschiedliche Hashwerte.

Beispiel 2


Map<PhoneNumber, String> m = new HashMap<PhoneNumber, String>();
m.put(new PhoneNumber(707, 867, 5309), "Jenny");

Das Folgende ist nur ein Beispiel, aber überschreiben wir hashCode.

Beispiel 3



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

Fortsetzen

[Read Effective Java] Kapitel 3 Punkt 10 "Immer toString überschreiben" https://qiita.com/Natsukii/items/6e2cd2e77e144048819d

Recommended Posts

[Read Effective Java] Kapitel 3 Punkt 9 "Wenn Sie equals überschreiben, überschreiben Sie immer hashCode"
[Read Effective Java] Kapitel 3 Punkt 10 "Immer toString überschreiben"
[Read Effective Java] Kapitel 3 Punkt 8 "Wenn Sie gleich überschreiben, befolgen Sie den allgemeinen Vertrag"
[Read Effective Java] Kapitel 2 Punkt 7 "Vermeiden Sie Finalizer"
[Read Effective Java] Kapitel 3 Punkt 12 "Berücksichtigung der Implementierung von Comparable"
[Read Effective Java] Kapitel 2 Punkt 6 "Veraltete Objektreferenzen entfernen"
[Read Effective Java] Kapitel 2 Punkt 4 "Unmöglichkeit der Instanziierung mit privatem Konstruktor erzwingen"
[Read Effective Java] Kapitel 2 Punkt 5 "Vermeiden Sie die Erstellung unnötiger Objekte"
[Read Effective Java] Kapitel 2 Punkt 2 "Betrachten Sie einen Builder, wenn Sie mit einer großen Anzahl von Konstruktorparametern konfrontiert werden."
[Read Effective Java] Kapitel 2 Punkt 1 "Betrachten Sie statische Factory-Methoden anstelle von Konstruktoren"
Effektives Java Kapitel 2
Effektives Java Kapitel 6 34-35
Effektives Java Kapitel 4 15-22
Effektives Java Kapitel 3
[Read Effective Java] Kapitel 2 Punkt 3 "Singleton-Eigenschaften mit privatem Konstruktor oder Aufzählungstyp erzwingen"
[Java] HashCode und gleich Überschreibung
Effektive Java 3rd Edition Kapitel 5 Generika
Effektive Java 3rd Edition Kapitel 8 Methoden
Verstehe gleich und hashCode in Java