2011-03-21 64 views
3

我有一個(不可變的)對象Group,我試圖在HashSet中使用它。但是,我得到奇怪的結果:對象相等,hashcodes相等,HashSet包含一個,但不包含另一個---如何?

// Position is another immutable class, GroupType is an enum 
Group t1 = new Group(new Position(0, 0), GroupType.ROW); 
Group t2 = new Group(new Position(0, 0), GroupType.ROW); 
Set<Group> s = new HashSet<Group>(); 
s.add(t1); 
System.out.format("t1.hashCode(): %d\nt2.hashCode(): %d\nt1.hashCode() == t2.hashCode(): %b\nt1.equals(t2): %b\nt2.equals(t1): %b\ns.contains(t1): %b\ns.contains(t2): %b\n", 
    t1.hashCode(), 
    t2.hashCode(), 
    t1.hashCode() == t2.hashCode(), 
    t1.equals(t2), 
    t2.equals(t1), 
    s.contains(t1), 
    s.contains(t2) 
    ); 

結果如下:

t1.hashCode(): 486656595 
t2.hashCode(): 486656595 
t1.hashCode() == t2.hashCode(): true 
t1.equals(t2): true 
t2.equals(t1): true 
s.contains(t1): true 
s.contains(t2): false 

T1和T2具有相同的散列碼,和equals()聲稱他們是相同的。 HashSet如何包含一個而不是另一個?

(不,沒有這些方法偷偷修改T1或T2;重複打印語句加納斯相同的結果。)

Group.equals()如下:

public boolean equals(Group g2) { 
    return (this.type.equals(g2.type)) && (this.basis.equals(g2.basis)); 
} 

類型是存儲的(最終)枚舉。基礎是位置,其具有以下等於:

public boolean equals(Position pos) { 
    return (x == pos.x) && (y == pos.y); 
} 

其中x和y是內部最終變量。

不過,我得到了相同的結果與替換它:

public boolean equals(Group g2) { 
    return true; 
} 
+4

't2.equals(t1)'打印什麼?你可以發佈'equals'的實現嗎? – 2011-03-21 19:52:12

+0

你能否提供'equals'代碼? – 2011-03-21 19:52:20

+0

沒有看到你的哈希碼或等於執行,你問我們是精神病 – 2011-03-21 19:59:18

回答

11

我懷疑......我猜測是你的equals方法是這樣的:

public boolean equals(Group other) 

這不會覆蓋內置的equals方法,這是HashSet將使用的方法。確保你的equals方法是:

@Override // Make the compiler check we're overriding something 
public boolean equals(Object other) 

測試此的另一種方式是:

Object o1 = t1; 
Object o2 = t2; 

System.out.println(o1.equals(o2)); 
System.out.println(o2.equals(o1)); 
+1

這就是爲什麼@Overrides註釋是偉大的;) – RoflcoptrException 2011-03-21 19:54:56

+0

@Roflcoptr:絕對。它應該是v1的語言的一部分:) – 2011-03-21 19:56:07

+1

根據症狀的描述,這種猜測多麼經常是正確的答案是可怕的 – 2011-03-21 20:01:21

相關問題