【问题标题】:How does a hashSet admit elementshashSet 如何接纳元素
【发布时间】:2015-07-10 09:22:04
【问题描述】:

我有一个需要添加到 HashSet 的对象列表,例如 List<Node> books。进一步说,没有两本书是平等的,因为它们的equals 方法都将返回 false;然而,假设他们的hashCode 方法每个都返回1。我正在使用这种极端情况,以便我可以完全理解录取是如何运作的。所以我的问题是:HashSet 会承认我所有的对象吗?

public class Book{
  ...
  @Override
  public boolean equals(Book other){
    return false;
  }

  @Override
  public int hashCode(){
    return 1;
  }
} 

回想一下,hashSet 不允许重复。

我对此感到疑惑,因为 hashSet 的名称正是使用对象的哈希值。该哈希是否与添加对象的 hashCode 有关?

是的,我是aware of

如果指定元素尚不存在,则将其添加到此集合中。 更正式地说,如果这个集合,则将指定的元素 e 添加到这个集合中 不包含元素 e2 使得 (e==null ? e2==null : e.equals(e2))。 如果该集合已经包含该元素,则调用离开该集合 不变并返回 false。

但是对象的hashCode和它在HashSet中的hash值有什么关系呢?

【问题讨论】:

标签: java equals hashcode hashset


【解决方案1】:

Setbuckets 组成,以加快搜索速度。 当新对象被添加到 Set 时,它的 hash 将使用对象的 hashCode() 方法进行评估。

然后,基于该 hashSet 决定将对象存储在哪个桶中。

然后,当您在 Set 中搜索对象时(例如使用 contains() 方法),将再次评估哈希值,然后 Set 遍历单个存储桶中的所有元素(而不是遍历 Set) 的所有元素。这使它更快,因为 - 通常 - 集合元素在许多桶中平均分布(或多或少)。

在您的情况下,所有对象都将存储在一个存储桶中,因此您的 SetList 的工作方式(即性能方面)并没有什么不同。

并回答最初的问题:是的,只要它们的equals() 正确实现,它就会存储您的所有对象。

【讨论】:

    【解决方案2】:

    我对你的问题有点困惑。 HashSet 将使用您添加的元素的hashCode() 方法(在本例中为List<Node> books)。因此,如果您添加 List 本身,HashSet 将在 List 上调用 hashCode,而不是在 Book 上,除非您单独添加 Book 元素。如果您单独添加它们,则会调用您在问题中定义的hashCode()

    附带说明,永远不要在您的hashCode() 中返回一个常量值。见Best implementation for hashCode method

    【讨论】:

      【解决方案3】:

      使用这个答案: How does a Java HashMap handle different objects with the same hash code? 和信息,HashSet<E> 只是一个HashMap<E, Object>

      【讨论】:

        猜你喜欢
        • 2015-07-28
        • 1970-01-01
        • 2012-02-15
        • 2015-03-26
        • 2018-09-02
        • 2020-04-06
        • 2015-08-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多