(Item 8) Override hashCode when you override equals()

(Item 8) Override hashCode when you override equals()

Incentive

public final class PhoneNumber {

        private final short areaCode;

        private final short exchange;

        private final short extension;

 

        public PhoneNumber(int areaCode, int exchange,

                int extension) {

                this.areaCode  = (short) areaCode;

                this.exchange  = (short) exchange;

                this.extension = (short) extension;

        }

 

        public boolean equals(Object o) {

                if (o == this)

                        return true;

                if (!(o instanceof PhoneNumber))

                        return false;

                PhoneNumber pn = (PhoneNumber)o;

                return pn.extension == extension &&

                        pn.exchange  == exchange  &&

                        pn.areaCode  == areaCode;

        }

        //...

}

Map m = new HashMap();

m.put(new PhoneNumber(408, 867, 5309), "Jenny");

m.get(new PhoneNumber(408, 867, 5309)) return null instead of "Jenny" !!!

Cause: Two equal instance have unequal hashcode

 

 

// Example of bad hasCode

public int hashCode() { return 42; }

Why? Because every object hashes to the same bucket, and hash tables degenerate to linked lists

 

Recipe for good hashCode() function

1.  Store some constant nonzero value, say 17, in an int variable called result.

2.  For each significant field f in your object (each field taken into account by the equals method, that is), do the following:

a. Compute an int hash code c for the field:

i.  If the field is a boolean, compute (f ? 0 : 1).

ii.  If the field is a byte, char, short, or int, compute (int)f.

iii.  If the field is a long, compute (int)(f ^ (f >>> 32)).

iv.  If the field is a float compute Float.floatToIntBits(f).

v.  If the field is a double, compute Double.doubleToLongBits(f), and then hash the resulting

long as in step 2.a.iii.

vi.  If the field is an object reference and this class's equals method compares the field by recursively invoking equals, recursively invoke hashCode on the field. If a more complex comparison is required, compute a “canonical representation” for this field and invoke on the canonical representation. If the value of the field is null, return 0 (or some other constant, but 0 is traditional).

vii.  If the field is an array, treat it as if each element were a separate field. That is, compute a hash code for each significant element by applying these rules recursively, and combine these values as described in step 2.b.

b.        Combine the hash code c computed in step a into result as follows:

result = 37*result + c;

3. Return result.

4. When you are done writing the hashCode method, ask yourself whether equal instances have equal hash codes. If not, figure out why and fix the problem.

 

// Sample hashCode

//Lazily initialized, cached hashCode

private volatile int hashCode = 0;  // (See Item 48)

 

public int hashCode() {

    if (hashCode == 0) {

        int result = 17;

        result = 37*result + areaCode;

        result = 37*result + exchange;

        result = 37*result + extension;

        hashCode = result;

    }

    return hashCode;

}

 

Do not be tempted to exclude significant  parts of an object from the hash code computation to improve performance. 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值