聊聊 Java 的 equals 和 hashCode 方法
Java 中的这个话题也是比较常遇到的,关于这块原先也是比较忽略的,但是仔细想想又有点遗忘了就在这里记一下
简单看下代码java.lang.Object#equals
1
2
3public boolean equals(Object obj) {
return (this == obj);
}
对于所有对象的父类,equals
方法其实对比的就是对象的地址,也就是是否是同一个对象,试想如果像 Integer 或者 String 这种,我们没有重写 equals
,那其实就等于是在用==
,可能就没法达到我们的目的,所以像 String 这种常用的 jdk 类都是默认重写了java.lang.String#equals
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
然后呢就是为啥一些书或者 effective java
中写了 equals
跟 hashCode
要一起重写,这里涉及到当对象作为 HashMap
的 key
的时候
首先 HashMap
会使用 hashCode
去判断是否在同一个槽里,然后在通过 equals
去判断是否是同一个 key
,是的话就替换,不是的话就链表接下去,如果不重写 hashCode
的话,默认的 object
的hashCode
是 native
方法,根据对象的地址生成的,这样其实对象的值相同的话,因为地址不同,HashMap
也会出现异常,所以需要重写,同时也需要重写 equals
方法,才能确认是同一个 key
,而不是落在同一个槽的不同 key
.