2012-09-04 15 views
5

Mam dwa zestawy:assertEquals Java ustawia

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 

równości metoda atrybut jest przesłonięta, według moich wymagań:

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()); 
} 

} 

podczas debugowania, metoda equals nie jest nawet nazywany!

Wszelkie pomysły?

+1

Zobacz także: [Zastępowanie równa i hashCode Java] (http://stackoverflow.com/questions/27581) – McDowell

+0

@McDowell: Dzięki! Wiedziałem, że jeśli hashCode zwraca różne wartości dla 2 obiektów, wtedy nie ma szansy na uzyskanie wartości true od połączenia równego. Spieszyłem się! :) – Razvan

Odpowiedz

13

Nie zastępujesz hashCode(), co oznacza, że ​​zostanie użyta domyślna implementacja. HashSet sprawdza pasujące kody haszujące najpierw, przed wywołaniem equals - w ten sposób udaje się tak skutecznie wyszukiwać potencjalne dopasowania. (Łatwo jest "wypełnić" liczbą całkowitą.)

Zasadniczo trzeba zastąpić hashCode w sposób zgodny z metodą equals.

+0

Co oznacza, że ​​jeśli 'równy' zwraca wartość true,' hashCode' również musi zwracać wartość true (tylko w tym kierunku). – brimborium

0

Jeśli zaznaczysz kod źródłowy HashSet metoda nazywa containsKey() który wywołuje getEntry(). Zgodnie z poniższym kodem źródłowym oczywiste jest, że do wywołania równań wymagana jest odpowiednia implementacja 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() metoda jest stosowana z równymi z AbstractCollection

Powiązane problemy