在《Effective Java》中写道:在每个覆盖了equals方法的类中,都必须覆盖hashCode方法。可见hashCode方法是非常重要的。编写hashCode方法要遵循两点原则:
(a)相等的对象必须拥有相等的散列码;
(b)不相等的对象的散列码尽量不要相等。
在一些基本类如Integer、Double、String都已实现了hashCode方法。如果编程时需要将自定义的类型作为hashMap、hashSet的Key,重载equals的同时,必须要重载hashCode方法。
下面的代码只重载了equals,没有重载hashCode。当put的两个Key为相等的对象时,它们的散列码并不相等,因此在HashMap中便产生了两组键值对。
import java.util.*;
public class Main{
public static void main(String[] args) {
class A{
int val1,val2;
public A(int x, int y) {
val1=x;val2=y;
}
/*@Override
public int hashCode() {
return Objects.hash(val1,val2);
}*/
@Override
public boolean equals(Object o) {
if(o instanceof A) { //检测o是否能转换成A的一个实例
A a=(A)o; //由于传入参数是object类,这里需要向下转型
return this.val1==a.val1&&this.val2==a.val2;
}
return false;
}
}
Map<A,Integer> m=new HashMap<>();
m.put(new A(1,2),1);
m.put(new A(1,2),2);
for(A a:m.keySet()) { //KeySet return a set view of the keys contained in this map
Integer i=m.get(a);
System.out.println(i);
}
}
}
其中,hashCode可以直接调用Objects类的静态方法hash,它其实是对Arrays.hashCode的封装。