hashSet如何允许元素

时间:2015-04-30 15:24:43

标签: java equals hashcode hashset

我有一个我需要添加到HashSet的对象列表,比如List<Node> books。进一步说,在他们的equals方法各自返回错误的意义上,没有两本书是平等的;但是,请说他们的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中的哈希值相关?

3 个答案:

答案 0 :(得分:3)

Set存储桶组成,以加快搜索速度。 将新对象添加到Set时,将使用对象的hashCode()方法评估其哈希

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

然后,当您在Set内搜索对象时(使用例如contains()方法),再次评估哈希值,然后Set迭代所有元素一个桶(而不是迭代Set的所有元素)。这使得它更快,因为 - 通常 - 设置元素在许多桶中平均分配(或多或少)。

在您的情况下,所有对象都将存储在一个存储桶中,因此SetList不会产生不同的效果(性能方面)。

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

答案 1 :(得分:1)

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

答案 2 :(得分:0)

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

作为旁注,请勿在{{1​​}}中返回固定值。见Best implementation for hashCode method