https://xiashengchao.iteye.com/blog/753409
HashSet中add的时候,会先比较hashcode是否相同,如果hashcode不同的话,直接写进去,如果相同的话会比较equals方法。
Why?
这是HASH冲突的一种处理链式的处理方法,即hashcode下会挂一条链表,这个链表里存hashcode相同的对象,所以如果hashcode相同的话,可能存在多个对象,还需要比较equal是否相同。HashSet add,如果hashcode相等,再调用equal这个方法来确保两个对象是不相等。、
那么重写了equals方法后,需要重写hashcode么?
答案是可定的,因为Java关于hashcode的规定是,equal相等那么hashcode一定相等,如果hashcode相等equal不一定相等。而equal默认比的是地址,如果重写了equal,重写成比较对象的某个值相等,那么就回出现类似于equal相等,但hashcode不相等的情况,这明显是逻辑不一定,在调用set集合的时候也会出现重复的对象放到了集合中。
下面的代码是验证hashset add的时候hashcode和equal的调用顺序:
package test;
import java.lang.*;
import java.util.*;
public class hello {
public static void main(String[] args) {
HashSet aa = new HashSet();
A a1 = new A();
B b1 = new B();
aa.add(a1);
aa.add(b1);
System.out.println(aa);
}
}
class A{
private static final String String = null;
public int a;
public int b;
public boolean equals(Object obj) {
System.out.println("A_equals");
return false;
}
public int hashCode(){
System.out.println("A_hashcode");
return 1;
}
public String toString(){
System.out.println("A");
return "A";
}
}
class B{
public int a;
public int b;
public boolean equals(Object obj){
System.out.println("B_equals");
return true;
}
public int hashCode(){
System.out.println("B_hashcode");
return 1;
}
public String toString(){
System.out.println("B");
return "B";
}
}
运行结果:
A_hashcode
B_hashcode
B_equals
A
[A]