我的问题是,"HashSet对象“可以复制元素吗?
如果我阅读了Set接口定义,我会看到:
不包含重复元素的集合。更正式地说,集合不包含一对元素e1和e2,使得e1.Eques(E2),最多包含一个null元素。顾名思义,这个接口建立了数学集抽象的模型。
现在我们要写一个简单的例子:
定义A类:
public class A {
@Override
public boolean equals(Object obj) {
return true;
}
}现在执行这段代码;
Set<A> set = new HashSet<A>();
set.add(new A());
set.add(new A());
System.out.println(set.toString());这就是结果:
com.maths.graphs.A@b9e9a3,com.maths.graphs.A@18806f7
为什么像HashSet这样实现Set接口的类包含重复的元素?
谢谢!!
发布于 2014-05-09 11:47:45
你破坏了等价物-hashcode合约。
如果重写equals方法,还必须重写hashCode()方法,以便:
两个相等的对象提供相同的散列,最好是不相等的对象极有可能给出不同的哈希码。
这一点很重要,因为许多对象(包括HashSet)使用哈希代码作为快速、高效的早期步骤,以消除不平等的对象。这就是这里所发生的事情,因为不同A的哈希代码将是不同的,因为它们仍然在使用在object中提供的.hashCode()实现。
如果按照下面的方式创建A类,则集合中不允许超过1A
public class A {
@Override
public boolean equals(Object obj) {
return true;
}
@Override
public int hashCode() {
int hash = 1; //any number since in this case all objects of class A are equal to everything
return hash;
}
}从javadoc
公共int hashCode() 返回对象的哈希代码值。哈希表(如HashMap提供的哈希表)支持此方法。 hashCode的总合同是:
大多数IDE将反对,如果您不包括覆盖的HashCode方法时,重叠的相等方法,并可以为您生成一个hashCode方法。
备注
严格地说,我的hashCode()方法并不完全满足合同的要求。由于A#equals( objects )等于,任何,包括不属于A类型的对象,都不可能完全满足合同的要求。理想情况下,等于方法也将改为下面的方法,以涵盖所有的基
@Override
public boolean equals(Object obj) {
if (obj instanceof A){
return true;
}else{
return false;
}
}发布于 2014-05-09 11:48:14
在这里,HashSet没有重复项,因为两个add方法在HashSet中添加了新的对象,它们是不同的对象。由于这个原因,集合的两个元素的哈希代码是不同的。尝试将代码更改为:
Set<A> set = new HashSet<A>();
A a = new A();
set.add(a);
set.add(a);
System.out.println(set.toString());你会发现集合中只有一个值。
或者只需在代码中添加以下内容并检查
@Override
public int hashCode() {
return 31;
}发布于 2015-09-10 08:13:31
您违反了hashCode()方法契约,即对于相同的密钥,它每次都应该返回相同的hashcode()
https://stackoverflow.com/questions/23563798
复制相似问题