2016-07-27 32 views
-2

我正在檢查Collection的contains()方法的代碼,無法找到hashcode()的用法。這裏是鏈接contains() method javadoccontains()的Collection框架不使用hashcode,而是使用equals(),爲什麼?

+0

爲什麼你會期望散列碼被使用?兩個不相等的對象可能巧合地具有相同的散列碼,但是關於集合論,它們都應該被允許佔據相同的集合。 –

+0

爲什麼不等於? –

+0

由於hashcode和equals方法的一致,我期望使用哈希碼。 – user6643247

回答

1

爲什麼沒有對ArrayList或LinkedList實現進行優化?

因爲它不一定是優化。

如果hashCode明顯比equals便宜,那麼只需在equals之前致電hashCode即可進行優化。如果您知道該對象的實現hashCode緩存哈希碼值和以前在該對象上稱爲hashCode,那麼它可能第一次調用hashCode更快。但是,如果這類原因是不正確的,那麼你很可能會發現:

  • hashCode調用至少貴爲equals調用(畢竟,hashCode不能「短路」就像一個良好實現的equals經常可以)和
  • 當哈希碼值相等時,您仍然需要撥打equals

分析變得很複雜......但我只想說,在很多情況下(考慮哈希碼的所有實現和平等相待,平等與不平等等元件的分佈)使用hashCode是一種抗優化。儘管如此,如果您有一個用例可以改進使用hashCode作爲優化的東西,那麼您可以自由地實現自己的自定義集合類。或者更好的是,優化元素類equalshashCode方法,以便equals自己檢查(高速緩存的)散列值。

+0

謝謝你的一個非常引人注目的答案,但如果我有一個非常複雜的等價方法,這是昂貴的。然後我猜hashcode可以是非常有用的。但我猜集合框架違反了hashcode和equals方法之間的協議。 – user6643247

+0

1)如果'equals'很複雜,那麼'hashCode'可能也必須複雜......否則你會得到很多散列衝突。 2)*「集合框架違反了hashcode和equals方法之間的協議。」*。事實上,它沒有。它根本不使用'hashCode' ...所以合約是沒有意義的。 –

+0

同意。謝謝!!! – user6643247

0

散列碼只是優化。最終,Collection#containsMap#get調用必須調用equals來檢查傳遞的對象是否真的存在,而不是恰好具有相同散列碼的另一個對象。如果您查看HashSetHashMap等特定實施方案,您會發現hashCode()作爲優化工具一路使用。

+0

是的。同意哈希集合,但在ArrayList實現中,你不會看到哈希碼。 – user6643247

+0

爲什麼沒有對ArrayList或q進行優化 – user6643247

+0

爲什麼沒有對ArrayList或LinkedList實現進行優化? – user6643247

0

ArrayList不需要使用hashCode()方法,因爲排序由插入順序決定。 hashCode()方法用於HashSet中的對象或用作HashMap中的鍵的對象。

+0

Hashcode是兩個引用是否指向同一個對象的猜測,這是通過equals方法確認的。那麼爲什麼hashcode不是用來猜測的......稍後equals可以測試對象的狀態。 – user6643247

+0

首先,Hascode不是兩個引用是否指向同一個對象的猜測。其次,「測試物體的狀態」究竟意味着什麼? –

+0

等於測試對象的狀態.... Hashcode是猜測...您爲某個計算附帶的對象獲取整數值。相同的整數也可以與其他對象一起使用。所以它是一個猜測,參考可以指向同一個對象。 – user6643247

相關問題