2012-09-04 2 views
5

は、私が二組持って設定しています。私の要件に応じて、上書きされのjavaのassertEquals

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メソッドがさえ呼ばれていません!

アイデア?

+1

参照の等号から使用されている:[オーバーライドは、JavaのequalsとhashCode(http://stackoverflow.com/questions/27581) – McDowell

+0

@McDowell:ありがとう!私は、hashCodeが2つのオブジェクトに対して異なる値を返す場合、equals呼び出しから真を得るチャンスがないことを知っていました。私は急いでいた! :) – Razvan

答えて

13

hashCode()をオーバーライドしていません。つまり、デフォルトの実装が使用されます。 HashSetは、一致するハッシュコードが最初にであることを確認する前に、equalsと呼びます。これは、可能性のある一致を効率的に見つける方法を管理する方法です。 (簡単に整数をバケットに入れます)

equalsメソッドと一貫して、hashCodeをオーバーライドする必要があります。

+0

これは、 'equals'がtrueを返す場合、' hashCode'もtrueを返さなければならないことを意味します(この方向でのみ)。 – brimborium

0

HashSetcontainsKey()のメソッド呼び出しでは、getEntry()が呼び出されます。以下のソースコードの通り、equalsを呼び出すには適切な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

関連する問題