[Read Effective Java] Chapter 3 Item 9 "When overriding equals, always override hashCode"

Always override hashCode when overriding equals

All classes that override equals will break the general contract for Object.hashCode if they don't also override hashCode.

Sample code

The code below overrides equals hashCode is not overriding

Example 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;
    }

    //incomplete-There is no hashCode method!
    
    ... //The rest is omitted
}

Suppose Example 1 is used in a HashMap. In Example 2, m.get (new PhoneNumber (707, 867, 5309)) is expected to return " Jenny ", but it returns null. Because we haven't overridden the hashCode, the put PhoneNumber and the get PhoneNumber have different hash values.

Example 2


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

The following is just an example, but let's override hashCode.

Example 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;
}

Continue

[Read Effective Java] Chapter 3 Item 10 "Always Override toString" https://qiita.com/Natsukii/items/6e2cd2e77e144048819d

Recommended Posts

[Read Effective Java] Chapter 3 Item 9 "When overriding equals, always override hashCode"
[Read Effective Java] Chapter 3 Item 10 "Always Override toString"
[Read Effective Java] Chapter 3 Item 8 "When overriding equals, follow the general contract"
[Read Effective Java] Chapter 2 Item 7 "Avoid Finalizers"
[Read Effective Java] Chapter 3 Item 12 "Considering Implementation of Comparable"
[Read Effective Java] Chapter 2 Item 6 "Remove obsolete object references"
[Read Effective Java] Chapter 2 Item 4 "Force uninstantiation with a private constructor"
[Read Effective Java] Chapter 2 Item 5 "Avoid the creation of unnecessary objects"
[Read Effective Java] Chapter 2 Item 2 "Consider a builder when faced with a large number of constructor parameters"
[Read Effective Java] Chapter 2 Item 1 "Consider static factory methods instead of constructors"
Effective Java Chapter 2
Effective Java Chapter 6 34-35
Effective Java Chapter 4 15-22
Effective Java Chapter 3
[Read Effective Java] Chapter 2 Item 3 "Force singleton characteristics with private constructor or enum type"
[Java] HashCode and equals overrides
Effective Java 3rd Edition Chapter 5 Generics
Effective Java 3rd Edition Chapter 8 Methods
Understanding equals and hashCode in Java