你的位置:首页 > Java教程

[Java教程]【Effective Java】5、覆盖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)));  }}