2013-05-09 32 views
13

如果我運行下面的代碼,那麼輸出是2,這意味着該集合包含2個元素。不過我認爲該集應該包含1,因爲兩個對象基於hashcode()值以及.equals()方法都是相等的。 似乎在我的理解中出現了一些明顯的錯誤?Java:添加到集合中的重複對象?

package HELLO; 

import java.util.HashSet; 
import java.util.Set; 

public class Test { 

    public static void main(String[] args) throws Exception { 
     Set<Alpha> s = new HashSet<Alpha>(); 
     Alpha a1 = new Alpha(); 
     Alpha a2 = new Alpha(); 
     s.add(a1); 
     s.add(a2); 
     System.out.println(s.size()); 
    } 
} 

class Alpha { 
    int a = 10; 

    public int hashcode() { 
     return a; 
    } 

    public boolean equals(Object obj) { 
     return (obj instanceof Alpha && ((Alpha) obj).a == this.a); 
    } 

    public String toString() { 
     return "Alpha : " + a; 
    } 
} 

回答

22

你的哈希Ç ODE方法不會覆蓋Object類的哈希Ç ODE方法,因此你的equals方法中斷合同,因爲它不符合的hashCode結果一致,你可以有對象是「相等的」,但具有不同的hashCode。

切記:在覆蓋方法時,您應始終使用@Override註釋,因爲這將幫助您捕獲此類錯誤和類似錯誤。

@Override // ** don't forget this annotation 
public int hashCode() { // *** note capitalization of the "C" 
    return a; 
} 

此外,您需要改進您的代碼格式,特別是在此處發佈代碼以供我們審覈時。如果符合標準,我們將能夠更好地理解您的代碼併爲您提供幫助(這就是標準存在的原因)。因此,請儘量保持縮進與同一塊中縮進相同級別的所有代碼行保持一致,並且您需要確保基本級代碼(包括導入,外部類聲明和其結束大括號)左對齊:

import java.util.HashSet; 
import java.util.Set; 

public class Test { 

    public static void main(String[] args) throws Exception { 
     Set<Alpha> s = new HashSet<Alpha>(); 
     Alpha a1 = new Alpha(); 
     Alpha a2 = new Alpha(); 
     s.add(a1); 
     s.add(a2); 
     System.out.println(s.size()); 
    } 
} 

class Alpha { 
    int a = 10; 

    @Override 
    public int hashCode() { 
     return a; 
    } 

    public String toString() { 
     return "Alpha : " + a; 
    } 

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

有關這個美麗的,請閱讀:Overriding equals and hashCode in Java

+0

謝謝!永遠不會忘記使用@Override :) – 2013-05-09 16:33:59

+0

@snow_leopard:這是一個很好的習慣。祝你好運! – 2013-05-09 16:38:25

+0

除了「@Override」之外,我還必須在equals函數中添加一行,否則該集無法檢測到重複項,並始終包含多次具有相同內容的對象:if(this.hashCode()== msg。 hashCode()) return true; – 2015-01-21 08:32:33

3

的@Overrides註釋是在父類的同名」要覆蓋的方法

@Override 
public int hashCode() { 
    return a; 
} 

@Override 
public boolean equals(Object obj) { 
    return (obj instanceof Alpha && ((Alpha) obj).a == this.a); 

} 

@Override 
public String toString() { 
    return "Alpha : " + a; 
} 
4

您方法公頃shcode應該被命名爲hashCode(大寫字母「C」)。

如果您計劃重寫方法,則應使用@Override註釋。

如果您已經使用了該註釋,那麼您之前會注意到該問題,因爲該代碼不會編譯。

相關問題