這兩個(gè)方法都是基類Object的方法,可以被子類重寫。
equals():比較兩個(gè)對(duì)象的引用的堆內(nèi)存地址是否相同,來判斷是否是同一個(gè)對(duì)象在JVM里。
hashCode():對(duì)對(duì)象的堆內(nèi)存地址做hashCode算法散列,便于查找的時(shí)候提高性能。
注:兩個(gè)對(duì)象equals()方法相同,那hashCode()的值一定相同。反之,則不一定。
1、String類equals()和hashCode()方法
/** The value is used for character storage. */
private final char value[];
/** Cache the hash code for the string */
private int hash; // Default to 0
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
//這一看源碼不就明白了么,這不就是兩個(gè)對(duì)象的值比較么
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;
}
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];//31人家外國(guó)人大神測(cè)試出來的,別問為什么。
}
hash = h;
}
return h;
}
然后我們想到 == 是個(gè)什么東東。栗子上

image.png

image.png
所以說 == 比較的是棧內(nèi)存里面的引用變量的值,而上面equals()方法比較的是堆內(nèi)存里面的對(duì)象值,不是內(nèi)存值。
驗(yàn)證

image.png

image.png
2、我們這么重寫一個(gè)對(duì)象里面的equals和hashCode()方法。
idea 有這種功能,在一個(gè)類里面按住Alt+Insert

image.png
如果不想比較id可以在后續(xù)的選項(xiàng)中把id去掉
@Data
class Man {
private Long id;
private String name;
private Integer age;
public Man(Long id, String name, Integer age) {
this.id = id;
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof Man)) {
return false;
}
Man man = (Man) o;
if (name != null ? !name.equals(man.name) : man.name != null) return false;
return age != null ? age.equals(man.age) : man.age == null;
}
@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + (name != null ? name.hashCode() : 0);
result = 31 * result + (age != null ? age.hashCode() : 0);
return result;
}
}

image.png

image.png