[英]How does the search algorithm work with objects in a java collection such as HashSet?
問題實際上是關於集合中動態變化的對象的。 是“包含”方法每次都去比較每個對象,還是做得很聰明?
如果集合中有10000個條目,我希望它能更巧妙地工作,但不確定。 或者如果沒有,可以通過添加一個掛鈎來優化它,該掛鈎將告訴收集對象更新已更改對象的哈希碼?
附加問題:
感謝您提供以下答案...我還能問一下ArrayList會發生什么情況嗎? 我在文檔中找不到任何不要將可變對象放入ArrayList的內容。 這是否意味着搜索算法會簡單地將其與每個對象的哈希碼進行比較?
他們對對象進行哈希處理並通過其哈希碼進行查找。 如果存在,它將比較對象本身。 這是因為具有相同散列的兩個或更多對象可能不是同一對象。
由於Java的哈希集合使用存儲桶(鏈接),因此它們必須查看存儲桶中的所有對象。 這些對象保存在鏈接列表中(不是java.util.LinkedList
,而是自定義列表)
通常這非常有效,並且HashSet.contains()
方法攤銷 O(1)(恆定時間)。
Java文檔對問題的第二部分有一個答案:
注意:如果將可變對象用作集合元素,則必須格外小心。 如果對象的值更改為影響相等比較的方式,而該對象是集合中的元素, 則不指定集合的行為 。 此禁止的一種特殊情況是,不允許集合將自身包含為元素。
當元素添加到集合中時, HashSet
計算該元素的哈希碼 。 它以一種非常有效的方式來存儲所有具有相同哈希碼的元素。
然后,當您調用contains()
,它只需要計算您要查找的值的哈希碼,並使用相同的哈希碼查找集合中的所有元素。 可能存在多個元素,因為哈希碼不是唯一的,但是具有匹配哈希碼的元素可能要比集合本身中的元素少得多。 然后,對每個匹配元素進行equals
檢查,直到找到匹配項或候選用盡為止。
編輯:要回答第二部分,我一讀就以某種方式錯過了它,您將無法再次找到該元素。 您不得以任何影響平等的方式更改哈希表中用作鍵的元素或哈希集中的元素,否則,您基本上會破壞事情。
簡單的答案是-不,沒有聰明的事情發生。 如果您希望對象的狀態發生變化,從而影響其hashCode()
和equals(...)
行為,則不得將其存儲在HashSet
或任何其他Set
。 要引用http://download.oracle.com/javase/6/docs/api/java/util/Set.html :
注意:如果將可變對象用作集合元素,則必須格外小心。 如果對象的值更改為影響
equals
比較的方式,而該對象是集合中的元素,則不指定集合的行為。 此禁止的一種特殊情況是,不允許集合將自身包含為元素。
HashSet
在HashSet
使用HashMap
。 因此, contains
操作使用對象中的hashCode()
方法檢查其是否存在於HashMap
實現的哈希表中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.