hashSet 如何接纳元素

How does a hashSet admit elements

我有一个需要添加到 HashSet 的对象列表,比方说 List<Node> books。进一步说,没有两本书在 equals 方法每本 return 都为假的意义上是相等的;但是,可以说他们的 hashCode 方法每个 return 1。我正在使用这个极端案例,以便我可以完全理解录取的工作原理。所以我的问题是:HashSet 会接受我所有的对象吗?

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

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

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

我对此感到疑惑,因为顾名思义,hashSet 使用对象的散列。该哈希值是否与要添加的对象的哈希码相关?

是的,我是 aware of

Adds the specified element to this set if it is not already present. More formally, adds the specified element e to this set if this set contains no element e2 such that (e==null ? e2==null : e.equals(e2)). If this set already contains the element, the call leaves the set unchanged and returns false.

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

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

的信息

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

附带说明一下,永远不要 return 在 hashCode() 中使用常量值。参见 Best implementation for hashCode method

一个Set个buckets个组成,加快查找速度。 将新对象添加到 Set 时,使用对象的 hashCode() 方法计算其 hash

然后,基于散列Set决定将对象存储在哪个桶中。

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

在您的情况下,所有对象都将存储在一个存储桶中,因此您的 SetList.

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