簡體   English   中英

更改存儲在基於哈希的集合中的對象的hashCode

[英]Changing hashCode of object stored in hash-based collection

我有一個基於哈希的對象集合,例如HashSetHashMap hashCode()的實現由於它是根據某些可變字段計算而可以隨時間變化時,我會遇到什么問題?

它如何影響休眠? 有任何原因為什么默認情況下讓hashCode()返回對象的ID不好? 如果重要的話,所有尚未持久化的對象都具有id = 0。

Hibernate映射的實體的hashCode的合理實現是什么? 設置后,ID是不可變的,但是在將實體保存到數據庫時並非如此。

我不擔心鍵值為0的12個實體的HashSet性能。 我關心的是對我的應用程序和Hibernate使用ID作為哈希碼是否安全,因為ID是在持久化時生成的,因此會發生變化。

如果同一對象的哈希碼隨時間變化,則結果基本上是不可預測的。 哈希集合使用哈希代碼將對象分配給存儲桶-如果您的哈希代碼突然更改,則該集合顯然不知道,因此它可能無法找到現有對象,因為它現在哈希到另一個存儲桶。

本身返回一個對象的ID還不錯,但是,如果其中許多對象都具有您提到的id = 0,則將降低哈希表的性能:所有具有相同哈希碼的對象都位於同一存儲桶中,因此您的哈希表格現在比線性列表更好。

更新:從理論上講,只要沒有其他人知道,您的哈希碼就可以更改-這恰好暗示了@bestsss在他的注釋中提到的內容,即從可能保存該對象的任何集合中刪除您的對象,然后再次插入一次哈希碼已更改。 實際上,一個更好的選擇是從對象的實際內容字段生成哈希碼,而不是依賴數據庫ID。

如果將對象添加到基於哈希的集合中,然后更改其狀態以更改其哈希碼(並暗示可能是.equals()調用中的行為),則可能會看到包括但不限於以下影響:

  • 您放入收藏夾的東西似乎已不存在
  • 提出與您要求不同的東西

這肯定不是您想要的。 因此,我建議僅在不可變字段中使用哈希碼。 通常通過將字段定為final字段並在構造函數中設置其值來完成此操作。

放置后,請勿更改基於哈希的集合中元素的哈希碼。

許多程序員陷入了陷阱。 您可能會認為哈希碼是集合中的一種地址 ,因此您無法在將元素放入集合后更改其地址。

Javadoc專門說內置集合不支持此功能。 所以不要這樣做。

暫無
暫無

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

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