2010-06-07 18 views
5

Ausführen dieses Code:Java HashSet und Datentyp Kurz, Inkompatibilität?

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()); 

    } 

} 

den Wert druckt 100.

Warum es diesen Wert nicht gedruckt werden?

+1

wie was, du willst, dass wir es versuchen ??? – pgras

Antwort

10
s.remove(i - 1); 

die Zeile über versucht Integer Objekte aus dem Satz zu entfernen, weil alle ganzzahligen Berechnungen in Java haben int (oder long) ergeben. Da das Set Short Objekte enthält, hat die Methode remove() keinen Effekt.

Diese (und ähnliche Probleme) ist der Hauptgrund, warum Sie fast nie short (und mehr so, Short) verwenden sollten. Die Verwendung einer Set Implementierung für autoboxierte Zahlen verursacht einen massiven (leicht 1000%) Overhead, so dass es ziemlich sinnlos ist, Platz zu sparen, indem Sie Short anstelle von Integer verwenden.

+0

... oder 'float' oder' double' ;-) –

6

Das Problem besteht darin, dass remove(i-1) ruft die Methode mit einem removeInteger Objekt, da i-1 vom Typ int (die in eine Auto-Integer geschachtelt werden).

Um sicherzustellen, dass Sie remove mit einem Short Objekt Gebrauch nennen dieses:

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

Oder expliziter above (Short.valueOf (i-1)); –

+0

@Steve: das würde nicht kompilieren, da du auch eine explizite Umwandlung benötigst. Es wird expliziter, aber auch ausführlicher. –

0

Die Art der i - 1 ist int, so wird es zu einem Integer autoboxed.

Normalerweise würden Sie erwarten, dass eine generische Auflistung verhindert, dass Sie Operationen ausführen, die Argumente vom falschen Typ haben, aber die Schnittstelle zu Set<E> ist ein bisschen locker.

Da die remove Methode der Set<E> ein Object nimmt eher als ein E, wird der Compiler Sie nicht warnen, dass Sie eine andere Art sind zu entfernen, was der Satz enthält.

Um eine Short zu erzwingen, übergeben Sie den numerischen Wert an (short). (Gießen (Short) nicht erlaubt ist, und Sie würden den numerischen Wert werfen müssen Short.valueOf verwenden)

0

Beachten Sie, dass das Add-Methode allgemein boolean add(E o) eingegeben wird so in Ihrem Fall von Stellen Sie die Add-Methode eine kurze nehmen, während die remove-Methode nicht generisch boolean remove(Object o) so i - 1 Autoboxen zu einem Integer eingegeben wird. Für jeden Wert von i new Short(i).equals(new Integer(i)) wird immer falsch sein.

Beachten Sie, dass Sie s.add(i - 1); einen Compilerfehler erhalten, da i - 1 eine Instanz von Ganzzahl wird und die Typen Integer und Short nicht übereinstimmen.