Effective Java5覆盖equals时总要覆盖hashcode

Posted cutter_point

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Effective Java5覆盖equals时总要覆盖hashcode相关的知识,希望对你有一定的参考价值。

package cn.xf.cp.ch02.item9;

import java.util.HashMap;
import java.util.Map;

public 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;
    }
    
    /*
    @Override
    //至于为什么使用31,这个是推荐值,研究表明这个数字用起来性能比较好
    public int hashCode()
    {
        int result = 17;
        result = 31 * result + areaCode;
        result = 31 * result + prefix;
        result = 31 * result + lineNumber;
        return result;
    }
    */
    
    //如果一个对象不是经常变动,而且开销比较大的话,就要考虑吧散列码缓存在对象内部
    //用volatile修饰的变量,线程在每次使用变量的时候,都会读取变量修改后的最的值。
    private volatile int hashcode;
    
    @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;
    }
    
    public static void main(String[] args)
    {
        Map<PhoneNumber, String> m = new HashMap<PhoneNumber, String>();
        m.put(new PhoneNumber(707, 867, 5309), "Jenny");
        //这里不会返回jenny哦,会返回null,这个是因为put对象吧他们放到不同的散列桶中
        System.out.println(m.get(new PhoneNumber(707, 867, 5309)));
    }
}

 

以上是关于Effective Java5覆盖equals时总要覆盖hashcode的主要内容,如果未能解决你的问题,请参考以下文章

Effective Java 第九条:覆盖equals时总要覆盖hashCode

Effective Java目录

覆盖equals()时总要覆盖hashCode()

覆盖equals时总要覆盖hashCode

Java 对象 覆盖equals时总要覆盖hashCode

第9条:覆盖equals时总要覆盖hashCode