【问题标题】:"Contains" implementation of ArrayList vs HashSetArrayList 与 HashSet 的“包含”实现
【发布时间】:2013-09-21 19:57:41
【问题描述】:

我有一个HashSet<Foo>。 我有一个对象是

  1. 等于集合的一个元素并且
  2. 具有与实现的同一对象匹配的哈希码。

如果我调用hashSet.contains(fooInstance),它仍然返回false

真正奇怪的是以下行返回true

new ArrayList<Foo>(hashSet).contains(fooInstance)

遗憾的是,要找出.contains() 实现的差异到底在哪里,结果比预期的要难。 但我认为我会很安全,因为 .equals().hashCode() 工作正常。

【问题讨论】:

  • Foo的hashCode稳定吗?
  • @MarkRotteveel 显然不是,根据当前描述,这是唯一可能导致 OP 声明的行为。
  • @Thihara 谢谢。这已经有帮助了。

标签: java collections equals contains hashcode


【解决方案1】:

最可能的原因是FoohashCode 不稳定,并且Foo 实例的hashCode() 的返回值在添加到@ 之后发生了变化987654325@。理想情况下,您只会将不可变对象添加到 HashSet

出于性能原因,HashSet 将计算出的hashCode 存储在其条目中,因此它不需要为每个get 重新计算它。因此,如果对象在HashSet 中发生更改,这将无法实现,并且您的对象将在HashSet 中有效地“丢失”(您仍然可以通过遍历所有元素来获取它,这本质上就是复制变成ArrayList 确实)。

【讨论】:

  • 这是否意味着contains 使用的 HashSet 与我稍后计算的不同?这可以解释为什么我仍然可以在集合中找到一个等于并具有相同哈希码的元素,但仍然没有“包含”。
  • @fancy:不,为什么会这样?这只是意味着在您将Foo 添加到HashSet 时,hashCode() 返回的值与其现在返回的值不同(并形成其他对象返回的值)。向我们展示您的FooequalshashCode 实现,我们可以告诉您更多信息。
  • @JoachimSauer 哈希码是否也标识了它所存储的特定哈希桶:不同的哈希码 -> 查找错误的桶,没有找到
  • @JoachimSauer 对不起,我拼错了。我的意思是“不同的哈希码”,而不是 HashSet。对吗?
  • @MarkRotteveel:是的,这是找不到它的另一个原因。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-06
  • 1970-01-01
  • 2014-03-05
  • 2021-01-13
  • 2014-07-11
  • 2018-01-18
相关资源
最近更新 更多