簡體   English   中英

在 Java 中使用任意對象作為 Map 鍵有什么缺點嗎?

[英]Any disadvantage to using arbitrary objects as Map keys in Java?

我的應用程序中有兩種對象,其中一種 object 恰好有一個對應的另一種 object。

跟蹤這種關系的明顯選擇是Map<type1, type2> ,例如 HashMap。 但不知何故,我很懷疑。 我可以使用 object 作為 Map 中的鍵,傳遞它,讓它也放在另一個集合中,並隨時從 Map 檢索它的伙伴嗎?

在創建 object 之后,我傳遞的只是一個標識符,對吧? 所以那里可能沒有問題。 如果我序列化和反序列化密鑰怎么辦?

還有其他注意事項嗎? 我是否應該使用其他東西來關聯 object 對,比如我自己生成的數字?

  1. 關鍵需要正確實現.equals().hashCode()
  2. 密鑰在用作密鑰時不得以任何方式更改其.hashCode()
  3. 理想情況下,任何用作 HashMap 中的鍵的HashMap都應該是不可變的。 這將自動確保 2. 始終為真。
  4. 否則可能會被 GC 處理的對象在用作鍵和/或值時可能會被保留。

我的應用程序中有兩種對象,其中一種 object 恰好有一個對應的另一種 object。

這聽起來確實像一個有關系,因此可以使用一個簡單的屬性來實現。

這取決於您選擇的 map 的實現:

  • HashMap使用equals()hashCode() 默認情況下(在對象中),這些基於 object 身份,除非您進行序列化/反序列化,否則它將正常工作。 根據 object 的內容正確實現 equals() 和 hashCode() 不會有任何問題,只要它是 hash Z1D78DC8ED51214E518B5114FEZ4 中的密鑰時不對其進行修改。

  • TreeMap使用compareTo() 沒有默認實現,因此您需要提供一個。 與上面實現 hashCode() 和 equals() 的限制相同。

您可以使用標准的 Map,但這樣做會在 Map 中保留對對象的強引用。 如果您的對象在另一個結構中被引用並且您需要 Map 只是為了將它們鏈接在一起,請考慮使用 WeakHashMap。

順便說一句,除非您必須將 object 的多個實例視為相等,否則您不必覆蓋 equals 和 hashCode...

我可以使用 object 作為 Map 中的鍵,傳遞它,讓它也放在另一個集合中,並隨時從 Map 檢索它的伙伴嗎?

是的,這里完全沒有問題。

在創建 object 之后,我傳遞的只是一個標識符,對吧? 所以那里可能沒有問題。 如果我序列化和反序列化密鑰怎么辦?

沒錯,您只是在傳遞一個引用——它們都將指向同一個實際的 object。 如果您序列化或反序列化 object,則會創建一個新的 object。 但是,如果您的 object 正確實現了 equals 和 hashCode,您應該仍然可以使用新的反序列化 object 從 map 檢索項目。

還有其他注意事項嗎? 我是否應該使用其他東西來關聯 object 對,比如我自己生成的數字?

至於注意事項,是的,當 object 在 Map 中時,您不能更改任何會導致 object 的 hashCode 發生變化的東西。

任何 object 都可以是 map 密鑰。 這里重要的是確保您為將用作 map 鍵的任何對象覆蓋.equals() 和.hashCode()。

您這樣做的原因是,如果您不這樣做,equals 將被理解為 object 相等,並且您能夠找到“相等”map 鍵的唯一方法是擁有原始 ZA8CFDE6331BD4B66AC96F8911 本身的句柄。

您覆蓋哈希碼是因為它需要與 equals 一致。 這樣一來,您定義的對象就等同於 hash。

故障點是 hashcode 和 equals 函數。 如果它們不能產生一致且正確的返回值,那么 Map 的行為就會很奇怪。 有效的 Java對它們有一個完整的部分,強烈推薦。

您可能會考慮 Google Collection 的BiMap

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM