我有一个我需要添加到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中的哈希值相关?
答案 0 :(得分:3)
Set
由存储桶组成,以加快搜索速度。
将新对象添加到Set
时,将使用对象的hashCode()
方法评估其哈希。
然后,基于 hash ,Set
决定对象将存储在哪个存储桶中。
然后,当您在Set
内搜索对象时(使用例如contains()
方法),再次评估哈希值,然后Set
迭代所有元素一个桶(而不是迭代Set
的所有元素)。这使得它更快,因为 - 通常 - 设置元素在许多桶中平均分配(或多或少)。
在您的情况下,所有对象都将存储在一个存储桶中,因此Set
与List
不会产生不同的效果(性能方面)。
回答原始问题:是的,只要正确实施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