Java hash and HashCode - TongtongLan/Java GitHub Wiki

在java.lang.Object 中

  • Object类中默认的Object.hashCode()方法使用对象的地址计算散列码

  • Object类中默认的Object.equals()只是比较对象的地址

因此如果要在使用了hash的集合(例如,HashMap、HashSet、LinkedHashSet、LinkedHashMap)中使用自定义对象(标准库中的类通常已经重写了与之相应的 equals() 和 hashCode() 方法)则必须重写equals() 和 hashCode() 方法

正确重写 equalss() 方法必须满足下列五个条件:

-> 《Java 编程思想》

  1. 自反性。对任意的x,x.equals(x) 一定返回值 true

  2. 对称性。对于任意的x,y,如果x.equals(y)为true,则y.equals(x)也为true

  3. 传递性。对于任意x,y和z,如果有x.equals(y)和y.equals(z)都为true,则x.equals(z)为true

  4. 一致性。对于任意x和y,如果对象中用于等价比较的信息没有改变,那么无论调用多少次x.equals(y)方法返回值应该保持一致

  5. 对任何不是 null 的 x,x.equals(null) 一定返回 null

为速度散列

首先要知道线性查询是最慢的查询方式。

  • 一种改进是保持键值的排序状态,然后采用Collection.binarySearch() 方法进行查询。

  • 另一种更快地方式即是散列。由于存储一组元素最快的数据结构是数组,可以使用数组来保存键值信息,但由于数组是固定大小的,无法为数组调整大小,解决方法是:**数组不保存键值本身,而是通过键对象生成一个数字,将其作为数组的下标,这个数字就是散列码。**散列码通过定义在Object中的或者自定义的 hashCode() 方法产生。