关于equals和hashCode的执行顺序的一些测试结果
先附上一些测试代码
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
public class Test {
private String name;
private int age;
private int num;
public Test(String name, int age, int num) {
this.name = name;
this.age = age;
this.num = num;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Test test = (Test) o;
return age == test.age &&
num == test.num &&
Objects.equals(name, test.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age, num);
}
public static void main(String[] args) {
Map<Test, String> map = new HashMap<>();
Test myTest1 = new Test("张三", 10, 1);
Test myTest2 = new Test("张三", 10, 1);
Test myTest3 = new Test("李四", 10, 1);
map.put(myTest1, "1");
System.out.println(map.containsKey(myTest1));
System.out.println(map.containsKey(myTest2));
System.out.println(map.containsKey(myTest3));
}
}
1 当调用map.put()方法时,会对key进行hash运算(具体可以看HashMap底层),这里调用了一次hashCode方法
2 当调用map.containsKey(myTest1)时,只调用了一次hashCode方法,没有调用equals方法(原因未知,猜测可能在底层做过了==进行地址判断,有知道的大牛请多指教)
3 当调用map.containsKey(myTest2)时,先调用了hashCode方法,相等,则继续调用equals方法
4 当调用map.containsKey(myTest3)时,先调用了hashCode方法,不等,不继续调用equals方法
equals判等的方式和hashCode判等的方式请自行搜索
总结:当调用containsKey时,会首先调用hashCode方法做初步判定,如果通过(不同的key可能算出来的结果相同!!!HashMap散列表的数组索引就是hash算法生成的,高16位^低16位 & 散列表的长度-1),继续调用equals方法判定,如果还是通过,就认定是相同的了。当然,要不要等还是看你这两个方法怎么实现
其实如果看过hashMap底层,可以发现,放key时,先通过hash算法找到散列表数组索引位置,然后遍历链表/红黑树,用equals判断是不是同一个key