java中重写了equals方法后,HashSet表中的contains方法为什么返回的还是false?

public boolean equals (Object obj){
if (obj instanceof Foo){
Foo foo=(Foo) obj ;
return value==foo.value;}
else{
return false;
}}
HashSet set=new HashSet();
set.add(new Foo(1));
set.contains(new Foo(1)); 这句话为什么返回的是false?我特意看过contains的API,上面说只要equals返回true,那么contains就返回true,注意我equals已经重写了,就是两个对象的valus属性相等就返回true,这我就不明白了。。难道和Hashcode有关系么?为什么API上没有强调?

HashSet 是无序无重复存储的,你new了两个Foo对象,但是值相同,HashSet里只会存一个,第二个new的Foo对象并没有存进去,contains()是根据equals()和hashCode()判断2个对象是否是同一个,你没重写hashCode(),系统默认按照地址计算hashCode,2个地址不同,hashCode也不同,返回当然是false。
加上public int hashCode(){
return this.value;
}
一般hashCode()和equals()都是同时重写的,不很好的覆盖hashCode()和equals() 会造成集合类工作故障!
而ArrayList是有序可重复存储的,2个Foo对象只要值相同就会返回true。
温馨提示:答案为网友推荐,仅供参考
第1个回答  2011-11-11
equals和hashcode方法要同时重写,并且要在equals为true的时候,hashCode必须要相同。这个已经是一种不成文的规定了,这两个方法要重写就要一起重写,而且IDE里也会只重写一个会视为警告。所以这两个方法要同时重写。
详细的可以去看HashMap的contains实现,哪里是equals和hashCode两个同时使用了,所以在有Map的时候,必须两个都要验证,但是在ArrayList里不严重hashCode所以你部重新这个hashCode也无所谓。本回答被提问者和网友采纳
第2个回答  2023-03-28
equals和hashcode方法要同时重写,并且add到set中的时候hashcode要一致。