java重写equals、hashCode方法

为什么要重新 hashCode方法

重写 equals() ,也需要重写 hashCode() 方法,否则 只是 调用 equals() 方法正确,但将对象放入 Set 等集合中,仍然认为是 不同的对象,因为这些集合是比较 hashCode() 方法返回值的

如何计算hashCode

在 eclipse、idea中有快捷方式

原理说明

定义一个int类型的变量:int result=1
对类中每一个 重要字段,也就是影响对象的值的字段,也就是 equals()方法里 有比较的字段,进行以下操作:

  • 计算这个字段的值filedHashValue
  • 执行 result = 31 * result + filedHashValue; 更新结果

如何计算每个重要字段的值

如果字段是基本数据类型,假设数值为f,根据类型做处理:

  • boolean,true返回1,false返回0
  • byte, char, short, int返回对应的int值
  • long,返回f^(f>>>32)
  • float,返回Float.floatToIntBits(f)
  • double,执行Double.doubleToLongBits(f)转为long,再返回compute(int)(f^(f>>>32))

如果字段是对象,如果是null,返回0,否则 调用 该对象的 hashCode() 方法

而如果字段是数组,通过 Arrays.hashCode(字段) 获取 hashCode 值

重写hashcode方法为什么用31

使用 31 的优点是可以用 移位 和 减法 来代替 乘法,以获得更好的性能:

31 * i == (i << 5) - i… 现代VM自动进行这种优化