2010-06-07 56 views
5

運行此代碼:Java HashSet和數據類型Short,incompatibility?

public class SomeSet { 

    public static void main(String[] args) { 

     Set<Short> s = new HashSet<Short>(); 

     for (short i = 0; i < 100; i++) { 

      s.add(i); 

      s.remove(i - 1); 

     } 

     System.out.println(s.size()); 

    } 

} 

將打印值100

爲什麼它打印這個值?

+1

喜歡什麼,你想讓我們試試看? – pgras 2010-06-07 09:07:35

回答

10
s.remove(i - 1); 

的線的上方將嘗試除去從該組Integer目的,因爲在Java所有整數計算具有int(或long)的結果。由於該集合包含Short對象,所以remove()方法不會有任何影響。

這個(以及類似的問題)是你幾乎從不使用short(以及更爲如此,Short)的主要原因。使用Set實現來包含自動綁定的數字會導致大量(容易1000%)的開銷,所以使用Short而不是Integer嘗試並節省空間是沒有意義的。

+0

...或「float」或「double」;-) – 2010-06-07 09:03:55

6

的問題是,remove(i-1)調用remove方法與Integer對象,因爲i-1int類型(它可以獲取自動盒裝入Integer)的。

要確保你叫removeShort對象使用這樣的:

s.remove((short) (i - 1)); 
+0

或更明確s.remove(Short.valueOf(i-1)); – 2010-06-07 15:14:01

+0

@Steve:它不會編譯,因爲你需要一個明確的演員。使其更加明確,但也更加冗長。 – 2010-06-07 15:43:02

0

類型的i - 1int,所以它被autoboxed爲整數。

通常情況下,您會希望獲得一個通用集合來阻止您執行具有錯誤類型參數的操作,但是到Set<E>的接口有點鬆散。

由於Set<E>remove方法需要一個Object而非E,編譯器不會警告你,你刪除一個不同的類型是什麼集包含。

要強制爲Short,請將數值轉換爲(short)。 (鑄造(Short)是不允許的,而且你必須投數值使用Short.valueOf

0

注意,add方法一般類型boolean add(E o)所以在您所設定的情況下,add方法將採取短,而刪除方法不是一般鍵入boolean remove(Object o),所以i - 1自動裝箱到一個整數。對於我的任何值new Short(i).equals(new Integer(i))將始終是錯誤的。

請注意,如果您嘗試s.add(i - 1);,則會出現編譯器錯誤,因爲i - 1將成爲Integer的一個實例,並且類型Integer和Short不匹配。