- 原生
equals()
底层源码通过==
来实现,比较的是两个对象(两个对象的引用地址)。 hashCode()
是jdk根据对象的地址或者字符串或者数字算出来的int类型的数值.- 两个对象的equals()相等(原生),hashCode()一定相等;
- 两个对象hashCode()相等,epuals()并不一定相等。
equals()
- 原生
equals()
底层源码通过==
来实现,比较的是两个对象(两个对象的引用地址)。 - 重写
equals()
用来比较两个对象的内容是否相等。
常用覆盖逻辑
1 | /** |
hashCode()
hashCode是jdk根据对象的地址或者字符串或者数字算出来的int类型的数值.
对象的地址或者字符串或者数字就是keys,通过一个函数算出hash.
hashCode=F(key);
- hashCode() 在散列表中才有用,在其它情况下没用。在散列表中hashCode() 的作用是获取对象的散列码,进而确定该对象在散列表中的位置;
- 两个对象的equals()相等(原生),hashCode()一定相等;
- 两个对象hashCode()相等,epuals()并不一定相等。
- 我们应该根据对象的特点,重写hashCode方法,尽量避免(3)提到的哈希冲突情况。
HashSet判定一个对象是否重复:
HashSet判定为重复对象。
未重写
equals()
和hashCode()
时:
code:1
2
3
4
5
6
7
8
9Person p1 = new Person("aaa",1);
Person p2 = p1;
Person p3 = new Person("bbb",1);
Set<Person> PS = Sets.newHashSet();
PS.add(p1);
PS.add(p2);
PS.add(p3);
System.out.println(p1.equals(p2));
System.out.printf(PS+"====》"+"p1.hashCode(%s)==>p2.hashCode(%s)==>p3.hashCode(%s)",p1.hashCode(),p2.hashCode(),p3.hashCode());console:
1
2true
[aaa - 1, bbb - 1]====》p1.hashCode(1047503754)==>p2.hashCode(1047503754)==>p3.hashCode(1722023916)我们知道原生equals()相等时,hashCode一定相等;
code:1
2
3
4
5
6
7
8
9Person p1 = new Person("aaa",1);
Person p2 = new Person("aaa",1);
Person p3 = new Person("bbb",1);
Set<Person> PS = Sets.newHashSet();
PS.add(p1);
PS.add(p2);
PS.add(p3);
System.out.println(p1.equals(p2));
System.out.printf(PS+"====》"+"p1.hashCode(%s)==>p2.hashCode(%s)==>p3.hashCode(%s)",p1.hashCode(),p2.hashCode(),p3.hashCode());console:
1
2false
[bbb - 1, aaa - 1, aaa - 1]====》p1.hashCode(1047503754)==>p2.hashCode(1722023916)==>p3.hashCode(2009787198)只重写
hashCode()
时:
code:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18private static class Person {
public int hashCode(){
int nameHash = name.toUpperCase().hashCode();
return nameHash ^ age;
}
}
public static void main(String[] args){
Person p1 = new Person("aaa",1);
Person p2 = new Person("aaa",1);
Person p3 = new Person("bbb",1);
Set<Person> PS = Sets.newHashSet();
PS.add(p1);
PS.add(p2);
PS.add(p3);
System.out.println(p1.equals(p2));
System.out.printf(PS+"====》"+"p1.hashCode(%s)==>p2.hashCode(%s)==>p3.hashCode(%s)",p1.hashCode(),p2.hashCode(),p3.hashCode());
}console:
1
2false
[aaa - 1, aaa - 1, bbb - 1]====》p1.hashCode(64544)==>p2.hashCode(64544)==>p3.hashCode(65539)只重写
equals()
时:
code:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33private static class Person {
public boolean equals(Object obj){
if(obj == null){
return false;
}
//如果是同一个对象返回true,反之返回false
if(this == obj){
return true;
}
//判断是否类型相同
if(this.getClass() != obj.getClass()){
return false;
}
Person person = (Person)obj;
return name.equals(person.name) && age==person.age;
}
}
public static void main(String[] args){
Person p1 = new Person("aaa",1);
Person p2 = new Person("aaa",1);
Person p3 = new Person("bbb",1);
Set<Person> PS = Sets.newHashSet();
PS.add(p1);
PS.add(p2);
PS.add(p3);
System.out.println(p1.equals(p2));
System.out.printf(PS+"====》"+"p1.hashCode(%s)==>p2.hashCode(%s)==>p3.hashCode(%s)",p1.hashCode(),p2.hashCode(),p3.hashCode());
}console:
1
2true
[bbb - 1, aaa - 1, aaa - 1]====》p1.hashCode(1047503754)==>p2.hashCode(1722023916)==>p3.hashCode(2009787198)同时重写
equals()
和hashCode()
时:
code:1
2
3
4
5
6
7
8
9
10
11public static void main(String[] args){
Person p1 = new Person("aaa",1);
Person p2 = new Person("aaa",1);
Person p3 = new Person("bbb",1);
Set<Person> PS = Sets.newHashSet();
PS.add(p1);
PS.add(p2);
PS.add(p3);
System.out.println(p1.equals(p2));
System.out.printf(PS+"====》"+"p1.hashCode(%s)==>p2.hashCode(%s)==>p3.hashCode(%s)",p1.hashCode(),p2.hashCode(),p3.hashCode());
}console:
1
2true
[aaa - 1, bbb - 1]====》p1.hashCode(64544)==>p2.hashCode(64544)==>p3.hashCode(65539)
至此我们推断HashSet的判重逻辑是,hashCode()
与equals()
同时满足