6

私は2つのセットを持っています:

 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

私の要件によれば、Attribute の 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 メソッドは呼び出されません!

何か案は?

4

2 に答える 2

13

をオーバーライドhashCode()していないため、デフォルトの実装が使用されます。呼び出す前に、最初HashSetに一致するハッシュ コードをチェックします。これが、潜在的な一致を非常に効率的に見つける方法です。(整数を「バケット化」するのは簡単です。)equals

hashCode基本的に、メソッドと一致する方法でオーバーライドする必要がありますequals

于 2012-09-04T10:27:37.183 に答える
0

を呼び出すHashSet contains()メソッド呼び出しのソース コードを確認すると、 . 以下のソース コードによると、 equals を呼び出すには適切な実装が必要であることは明らかです。containsKey()getEntry()hashcode()

/**
 * 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;
}

PS:Contains()メソッドは次の等号から使用されますAbstractCollection

于 2012-09-04T10:59:39.390 に答える