2012-04-25 67 views
0

應用程序會說如果用戶猜測他已經引入了兩種顏色組合。獲取哈希映射中的等價元素

我使用HashMap來保存「TwoColors」對象和布爾值。該TwoColors類是下一個:

public class TwoColors{ 
    public MyColor color1; 
    public MyColor color2; 
    public TwoColors(MyColor color1, MyColor color2){ 
     this.color1 = color1; 
     this.color2 = color2; 
    } 
    @Override 
    public boolean equals(Object obj) { 
     TwoColors o = (TwoColors) obj; 
     return color1 == o.color1 && color2 == o.color2; 
    } 
} 

而且MyColor是

public enum MyColor{ 
    RED,BLUE,YELLOW,BROWN; 
} 

我測試把一個兩色對象密鑰和打印其值

public static void main(String[] args){ 
    HashMap<TwoColors, Boolean> hash = new HashMap<TwoColors, Boolean>(); 
    hash.put(new TwoColors(MyColor.RED,MyColor.BLUE),new Boolean(true)); 
    System.out.println(hash.get(new TwoColors(MyColor.RED,MyColor.BLUE))); 
} 

上面的代碼輸出null枚舉儘管我已經覆蓋了TwoColors的equals方法。任何想法我在這裏想念什麼?

+1

如果重寫等於要重寫了hashCode以及一個好主意。 – 2012-04-25 02:45:31

回答

2

當你覆蓋等於你應該總是覆蓋散列碼,如果你不這樣做,當你嘗試通過調用get查找值,你的散列映射無法找到它。

閱讀this後瞭解。

缺省的hashCode你可以得到使用Eclipse:

@Override 
    public int hashCode() { 
     final int prime = 31; 
     int result = 1; 
     result = prime * result + ((color1 == null) ? 0 : color1.hashCode()); 
     result = prime * result + ((color2 == null) ? 0 : color2.hashCode()); 
     return result; 
    } 

而且你平等的實現是不生產代碼,這意味着它不會正確地實現它。您的實施對ClassCastException開放,因爲您盲目地將其轉換爲MyColor,所以您的實現傾向於NullPointerException

它應該像這樣的:

@Override 
    public boolean equals(Object obj) { 
     if (this == obj) 
      return true; 
     if (obj == null) 
      return false; 
     if (getClass() != obj.getClass()) 
      return false; 
     TwoColors other = (TwoColors) obj; 
     if (color1 != other.color1) 
      return false; 
     if (color2 != other.color2) 
      return false; 
     return true; 
    } 

之前檢查的字段值檢查,如果兩個引用相同,檢查空,檢查類的平等和最終檢查的字段值。

雖然阿帕奇還具有HashCodeBuilderEqualsBuilder

+0

明白了,謝謝。關於等號代碼,我把它放在了一起,讓它看起來更乾淨,但是再次感謝你 – 2012-04-25 03:54:33

1

從Java文檔:

注意,這是通常需要覆蓋hashCode方法每當這個方法[equals]被覆蓋,以便維持hashCode方法的一般合約,它聲明相等的對象必須具有相同的散列碼。

由於MyColor是一個枚舉,將此代碼添加到您的類應該修復它:

@Override 
public int hashCode() { 
    return color1.ordinal() + 31*color2.ordinal(); 
}