【Java基礎】equals和hashcode
一、equals
equals是Object類的其中一個方法,預設的實現方法為
public boolean equals(Object obj) {
return (this == obj);
}
可以看到,預設方法僅僅是判斷是否為同一物件。因為各個類都是繼承自Object類,所以各個類可以根據需要自己重寫equals方法,如String類等。String類重寫的equals方法如下:
public 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; }
不僅僅看是否為同一物件,還會比較物件中儲存內容是否相同。
經常被討論到的就是equals的幾個特性:自反性、對稱性、傳遞性、一致性。這些特性就不展開了,網上到處都有,也很好理解。
所以兩個物件呼叫equals結果返回的是true,則一定是相等的,可信的。
二、hashcode
hashcode也是Object類中的一個方法,
public native int hashCode();
hashcode是一個native方法,Object沒有給出具體實現。
hashcode可以產生物件的一個識別碼,用來和別的物件進行區分,但是它不如equals比較的全面和可靠。比如比較兩個人是否為同一個人,hashcode即產生每個人的識別碼,如出生日期,兩個人的出生日期相等但不一定就是同一個人,equals不僅要比較出生日期,還要比較姓名等別的資訊。
那既然如此,為什麼不都用equals來比較,還存在一個hashcode方法呢?
1、hashcode方法雖然不如equals比較的全面和可靠,但是它可以反向的區分出兩個物件不相等:兩個物件如果相等,則hashcode一定相等;如果hashcode不相等,則兩個物件一定不相等。
2、從String類重寫的equals方法可以看出,equals方法比較太繁瑣,沒有hashcode便捷。
所以可以採用先hashcode判斷一輪,hashcode相等,再用equals判斷,equals相等才是真正的相等;hashcode不相等,則一定不相等,就不用equals再判斷了,提高了效率。容器類如HashSet、HashMap等就是這麼實現的。
正因為hashcode和equals配合使用,所以重寫equals方法的同時要記得重寫hashcode方法,不然就可能達不到上面所說的比較效果。