《Effective Java》读书笔记08--覆盖hashCode
一、覆盖hashCode
在每一个覆盖equals方法的类中必须覆盖hashCode方法,如果你想让该类能够用于基于散列的集合中,如HashMap,HashSet和Hashtable。
Object.hashCode通用约定
1、在应用程序的执行期间,只要对象的equals方法的比较操作所用到的信息没有被修改,那么对这个同一对象调用多次,hashCode方法必须始终如一地返回同一个整数。在同一个应用程序的多次执行过程中,每次执行所返回的整数可以不一致。
2、如果两个对象根据equals(Object)方法比较是相等的,那么调用这两个对象中任意一个对象的hashCode方法都必须产生同样的整数结果。反之,如果两个对象hashCode方法返回整数结果一样,则不代表两个对象相等,因为equals方法可以被重载。
3、如果两个对象根据equals(Object)方法比较是不相等的,那么调用这两个对象中任意一个对象的hashCode方法,则不一定要产生不同的整数结果。但,如果能让不同的对象产生不同的整数结果,则有可能提高散列表的性能。
二、没覆盖hashCode的糟糕实践
下面是一个PhoneNumber类
//延迟初始化hashCode private volatile int hashCode; // (See Item 71) @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; }1、覆盖equals方法是必须覆盖hashCode方法
2、覆盖hashCode方法要遵守通用约定,实现时可以参考三种方法
3、当hashCode计算开销大时,可以考虑延迟初始化hashCode
4、不要试图从散列码计算中排除掉一个对象的关键部分来提供性能