Effective Java代碼規則之十一:覆蓋equals時總要覆蓋hashCode

1、解釋

  • 為什麼要覆蓋hashCode

在每個覆蓋了equals方法的類中, 都必須覆蓋hashCode方法。如果不這樣做的話,就會違反hashCode的通用約定,從而導致該類無法結合所有基於散列的集合一起正常運作,這類集合包括HashMap和HashSet ,舉個例子:

private String loginId;
private String password;
private String name;
public UserBean(String loginId, String password, String name) {
this.loginId = loginId;
this.password = password;
this.name = name;
}
public static void main(String[] args) {
Map<userbean> m = new HashMap<>();
UserBean u1 = new UserBean("111", "111", "stanley");
UserBean u2 = new UserBean("111", "111", "stanley");
m.put(u1, "stanley");
System.out.println("u1.equals(u2): " + u1.equals(u2));
System.out.println("u2.equals(u1): " + u2.equals(u1));
System.out.println("get u1 from hashmap: " + m.get(u1));
System.out.println("get u2 from hashmap: " + m.get(u2));
}
/<userbean>

該類覆蓋了equals方法,但是沒有覆蓋hashCode方法,執行結果如下:

u1.equals(u2): true
u2.equals(u1): true
get u1 from hashmap: stanley
get u2 from hashmap: null

因為UserBean類沒有覆蓋hashcode方法,從而導致兩個相等的實例具有不相等的散列碼。

  • hashCode的通用約定:

在應用程序的執行期間,只要對象的equals方法的比較操作所用到的信息沒有改變,那麼對於這同一個對象調用多次hashcode都必須返回同一個整數。

如果兩個對象相等(用equals(Object)方法比較),那麼這兩個對象的hashCode值也必須相等。

如果兩個對象不相等(用equals(Object)方法比較),那麼這兩個對象的hashCode值不一定不相等(最好不相等)。

2、實現高質量hashCode的方法

2.1、聲明一個int變量並命名為esult,將它初始化為對象中第一個關鍵域的散列碼

2.2、為對象計算int類型的散列碼c

  • 如果該域是基本類型,則計算Type.hashCode(f),這裡的Type 是裝箱基本類型的類,與f的類型相對應
  • 如果該域是一個對象引用,則同樣為這個域遞歸地調用hashCode
  • 如果該域是一個數組,可以使用Arrays.hashCode方法

2.3、按照下面的公式,把步驟 2.2中計算得到的散列碼c合併到result中

 result = 31 * result + c;

這裡提個問題:為什麼選擇數字31作為生成hashCode值的乘數?

3、最佳實踐

在實際工作中,覆蓋hashCode方法比較麻煩,通常我們使用IDE工具自帶的生成功能:

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((loginId == null) ? 0 : loginId.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((password == null) ? 0 : password.hashCode());
return result;
}
Effective Java代碼規則之十一:覆蓋equals時總要覆蓋hashCode

專業從事軟件研發工作多年,在軟件設計、開發、測試、研發管理等領域裡經驗豐富,感興趣的朋友可以關注我的頭條號,相信一定會有所收穫。

如果有軟件研發方面的問題,可以諮詢我。

謝謝!


分享到:


相關文章: