[英]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.