2015-06-22 62 views
1

這裏是其產生的HashSet大小3代替2爲什麼對象不相同添加有相同的值,HashSet的,甚至的hashCode和equals被覆寫

package dump.test; 
import java.util.*; 
public class WrappedString { 
    private String s; 
    public WrappedString(String s) { this.s = s; } 
    public static void main(String[] args) { 
     HashSet<Object> hs = new HashSet<Object>(); 
     WrappedString ws1 = new WrappedString("aardvark"); 
     WrappedString ws2 = new WrappedString("aardvark"); 
     String s1 = new String("aardvark"); 
     String s2 = new String("aardvark"); 
     hs.add(ws1); hs.add(ws2); hs.add(s1); hs.add(s2); 
     System.out.println(hs.size()+hs.toString()); 
    } 
    public boolean equals(Object aSong) { 
     String s = aSong.toString(); 
     System.out.println(s); 
     return s.equals(this.s); 
    } 
    public int hashCode() { 
     System.out.println(this.s + "-" + this.s.hashCode()); 
     return this.s.hashCode(); 
    } 
    /*public int compareTo(Object aSong) { 
     String s = aSong.toString(); 
     return this.s.compareTo(s); 
    }*/ 
} 
代碼

它總是打印下面輸出如果equals和hashCode被覆蓋 enter image description here

你可以看到具有輸出相同的代碼,但算作不同,產生的數爲3

兩個對象,這是如果不重寫equals和hashCode enter image description here

請協助我如何工作。

+0

你的平等方法甚至不會爲'ws1.equals(ws2)' –

回答

3

問題是你的情況是不對稱的。如果實現決定調用String實例上的equals,並將您的類作爲參數,那麼它肯定會返回false,因此您的代碼將不會始終工作。

+0

返回true謝謝塞巴斯蒂安!以上代碼中的兩個WrappedString對象可以做出哪些努力是相同的。我想在上面的代碼中計算爲2。 –

+0

添加公共字符串toString(){return this.s; }清除了我的困惑。 –

2

Javadoc中的Set接口:

不包含重複元素的集合。更正式地,集合不包含e1和e2這樣的元素對,使得e1.equals(e2)和至多一個空元素。正如其名稱所暗示的那樣,該界面模擬數學集抽象。

因此,HashSet在添加新元素之前檢查equals(Object)。由於第二個字符串等於第一個字符串,因此不會添加。在你的WrappedString上,你不是覆蓋equals(Object),所以,你使用的是從Object繼承的,它只是檢查對象ID(在你的情況下爲659e0bfd2a139a55)。

+0

謝謝jpkrohling!如果遇到對象ID 2fcf3776(按照第一張圖片),怎麼辦?所以我認爲這兩個ID是相同的,等於會發現值太相同,它將被添加爲一個集合,但它不是。以上代碼中的兩個WrappedString對象可以做出哪些努力是相同的。我想在上面的代碼中計算爲2。 –

+0

事實上,我的答案並非100%正確,因爲對象比較了對象的內部ID。爲了你的代碼的工作,我會說你需要讓你的WrappedString#equals來比較內部字符串,並讓你的toString返回底層字符串。 – jpkrohling

+0

榮譽jpkrohling!它就像你說的那樣工作。我需要重寫一個工廠方法,toString並使其返回底層字符串值。以前,它無法從對象轉換爲字符串,並且可能會導致不同的對象,儘管具有相同的對象ID。下面的小片段作品: public String toString(){ \t \t return this。S; \t} –

0

加入

public String toString() { return this.s; }

清除我的困惑。以前,它無法將鑄造對象的真實值轉換爲字符串,並且需要覆蓋toString以返回基礎值。

相關問題