Java HashSet.equals()是否以恒定时间运行?

Java HashSet.equals()是否以恒定时间运行?,java,collections,big-o,hashset,time-complexity,Java,Collections,Big O,Hashset,Time Complexity,只是想知道HashSet.equals(另一个HashSet)是否在恒定时间内运行(也使用ConcurrentHashSet作为参数),出于效率原因,我假设它会运行。看不到任何提到它的内容,我正在构建的框架的一部分依赖于功能(不希望花费太长时间!) 编辑:抱歉,我意识到HashSet.equals()不可能在固定时间内运行,因为元素可以更改,而映射中元素的哈希代码保持不变。因此,解决这个问题的最佳方法是使用hashcode。但它有代码气味吗?就我从代码中看到的,它是以线性时间运行的。迭代集合并比

只是想知道
HashSet.equals(另一个HashSet)
是否在恒定时间内运行(也使用
ConcurrentHashSet
作为参数),出于效率原因,我假设它会运行。看不到任何提到它的内容,我正在构建的框架的一部分依赖于功能(不希望花费太长时间!)


编辑:抱歉,我意识到HashSet.equals()不可能在固定时间内运行,因为元素可以更改,而映射中元素的哈希代码保持不变。因此,解决这个问题的最佳方法是使用hashcode。但它有代码气味吗?

就我从代码中看到的,它是以线性时间运行的。迭代集合并比较每个元素:


AbstractSet
中的
equals(..
)调用
containsAll(..)
中的
AbstractCollection
,它获取迭代器并调用
包含(..)
每个元素,然后依次调用
映射.containsKey(..)
它是
O(1)
。因此,如果我没有弄错的话,
O(n)

由于要求两个
集合
对象的元素必须相同,我认为在一般情况下(例如,没有对内容类型的附加限制),不可能在O(1)中正确实现这一点

一个明显的例外是,如果输入集具有不同的大小,则
equals()
操作可以在O(1)中轻松完成(只要
size()
本身是O(1))


您可以编写一个薄包装器,在每次计算时缓存
hashCode()
(并在
Set
更改时丢弃它)。这将允许您在两个
Set
对象不相同的大多数情况下保持恒定的运行时间。当您必须等于
设置
对象时(或在哈希冲突的情况下),您仍将有一个O(n)运行时。

查看典型的
显示它确实包含所有
。每个对contains的检查都将是O(1),其中N个必须进行,所以我估计是O(N)。

它怎么可能在恒定时间内运行?唯一合理的实现(也是使用的实现,如果您检查API文档,您可以看到)是迭代其中一个集合,并为每个元素检查另一个是否包含它,这基本上是一个O(n+m)操作。

看看代码。它怎么可能是O(1)不管元素的数量有多少?@BrokenGlass如果“第一个”元素不同吗?@Tom Hawtin:这是一种特殊情况,不包括一般的大O-最坏的情况是你必须比较所有元素,即O(n)@BrokenGlass匹配的第一个元素不是典型的特殊情况吗?另请参见“快速排序的最坏情况”,例如,“我认为不可能在O(n)中正确实现它”-您能详细说明一下这是什么意思吗?如果
equals()
需要访问每个元素(在两个集合中)一次(或恒定次数),这意味着
O(n)
其中
n
是集合的大小。@matt b:那是一个打字错误(或者可能是thinko),我想改为写O(1)(现在已经修复了)。非常正确。我忘记了equals通常是如何实现的,以及该实现如何对相等性进行自定义检查。同意(并更新)。单凭代码是一种不好的解释方式。Jon Skeet的答案更好,因为文档更清晰。