我有两套:
Set<Attribute> set1 = new HashSet<Attribute>(5);
Set<Attribute> set2 = new HashSet<Attribute>(5);
//add 5 attribute objects to each of them. (not necessarily the same objects)
assertEquals(set1,set2); //<--- returns false, even though
//the added attribute objects are equal
根据我的要求,覆盖了属性的equals方法:
public abstract class Attribute implements Serializable{
public int attribute;
public abstract boolean isNumerical();
@Override
public boolean equals(Object other){
if(!(other instanceof Attribute)){
return false;
}
Attribute otherAttribute = (Attribute)other;
return (this.attribute == otherAttribute.attribute &&
this.isNumerical() == otherAttribute.isNumerical());
}
}
调试时,甚至不调用equals方法!
有什么想法吗?
答案 0 :(得分:13)
您没有覆盖hashCode()
,这意味着将使用默认实现。 HashSet
在调用equals
之前检查匹配的哈希码首先 - 这就是它如何有效地找到潜在匹配的方法。 (很容易“挖出”整数。)
基本上,您需要以与hashCode
方法一致的方式覆盖equals
。
答案 1 :(得分:0)
如果您查看调用HashSet
的{{1}} contains()
方法调用containsKey()
的源代码。根据以下源代码,很明显需要一个适当的getEntry()
实现来调用equals。
hashcode()
PS:/**
* Returns the entry associated with the specified key in the
* HashMap. Returns null if the HashMap contains no mapping
* for the key.
*/
final Entry<K,V> getEntry(Object key) {
int hash = (key == null) ? 0 : hash(key.hashCode());
for (Entry<K,V> e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
return e;
}
return null;
}
方法使用等于Contains()