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。
equals和hashcode方法要同时重写,并且要在equals为true的时候,hashCode必须要相同。这个已经是一种不成文的规定了,这两个方法要重写就要一起重写,而且IDE里也会只重写一个会视为警告。所以这两个方法要同时重写。
详细的可以去看HashMap的contains实现,哪里是equals和hashCode两个同时使用了,所以在有Map的时候,必须两个都要验证,但是在ArrayList里不严重hashCode所以你部重新这个hashCode也无所谓。
equals和hashcode方法要同时重写,并且add到set中的时候hashcode要一致。