2016-02-14 36 views
2

由於我的知識集基本上有兩個方法equals()和hashcode(),根據它確定的值包含的值相等並避免重複輸入,但是在下面的程序中我得到困惑,即使包裝類也有兩種方法重寫,那麼爲什麼它接受重複值?爲什麼設置允許重複的字節整數和長整型值

代碼:

Collection col=new LinkedHashSet(); 
col.add(new Long(65)); 
col.add(new Byte((byte) 65)); 
col.add(new Integer(65)); 
col.add("A"); 

System.out.println(col); 

答:65,65,65,A] 但我預期[65,A]

回答

7

一個Long實例可以永遠不等於一個Integer實例即使兩者具有相同的數值,它也永遠不會等於Byte實例。你放入Set的3個實例並不相同。

見,例如,Integerequals

public boolean equals(Object obj) { 
    if (obj instanceof Integer) { 
     return value == ((Integer)obj).intValue(); 
    } 
    return false; 
} 

兩個實例必須是相同的類型,以便爲彼此相等(必要條件)。

+0

長L =新龍(65); \t \t System.out.println(l); \t \t Integer it = new Integer(65); \t \t System.out.println(it); \t \t System.out.println(l.equals(it)); – pranta

+0

謝謝你了! – pranta

1

設置不允許重複的值。這裏的問題是什麼是重複的,什麼不重要。

重複值是那些相同類型,具有相同的hashCode(),並且在比較時也返回true。不同類型的對象(在你的例子中是Byte和Long)在這些術語中是不相等的。

如果您想然而把不同的數字類型的值轉換成集,並享受跨類型的行爲,你可以使用TreeSet與自定義Comparator,只有不考慮類型考慮比較。

+0

讓我挑剔(對不起):「重複的值是那些同類型的[...]」 =>雖然它應該是真實的,它是完全由_equals_實施,而不是一個集合的特性。既然這樣,這句話是有點誤導,不是嗎? – Seelenvirtuose

+0

你是對的,它是等於執行。然而,OP使用已經實現了equals的原始包裝。 – AlexR

2

這裏是什麼javadocInteger.equals(Object)說:

比較此對象與指定對象。結果爲真當且僅當參數不是null並且是一個Integer對象包含與此對象相同的int值。

換句話說,一個Integer對象不能等於一個也不是Integer對象的對象。這同樣適用於所有的基本包裝類。

因此,根據HashSet的語義,您示例中的那4個對象不相同,因此不會重複。


不幸的是,如果你使用HashSet或任何其他標準的Java基於哈希表類的,與標準的包裝類一起,對於這個沒有解決方法。

但是:

  • 如果你使用TreeSet或類似的,你可以使用自定義Comparator對象解決此問題。

  • Guava中有一個替代的哈希表實現,允許您提供外部equals和hashCode實現。

  • 你可以用不同的語義創建你自己的包裝類,用於equals和hashcode到標準類。不幸的是,這些不會與其他事物進行互操作。例如Java自動裝箱/自動拆箱。

相關問題