Java HashSet and data type Short, incompatibility?
Running this code:
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());
}
}
Will print the value 100.开发者_开发问答
Why does it print this value?
s.remove(i - 1);
The line above will attempt to remove Integer
objects from the set, because all integer calculations in Java have int
(or long
) results. Since the set contains Short
objects, the remove()
method will not have any effect.
This (and similar problems) is the main reason why you should almost never use short
(and, more so, Short
). Using a Set
implementation to contain autoboxed numbers incurs a massive (easily 1000%) overhead, so it's rather pointless to try and save space by using Short
rather than Integer
.
The problem is that remove(i-1)
calls the remove
method with an Integer
object, since i-1
is of type int
(which gets auto-boxed into an Integer
).
To make sure that you call remove
with a Short
object use this:
s.remove((short) (i - 1));
The type of i - 1
is int
, so it gets autoboxed to an Integer.
Normally you'd expect a generic collection to prevent you performing operations which have arguments of the wrong type, but the interface to Set<E>
is a bit loose.
Because the remove method of Set<E>
takes an Object
rather than an E
, the compiler doesn't warn you that you're removing a different type to what the set contains.
To force it to be a Short
, cast the numeric value to (short)
. (casting to (Short)
isn't allowed, and you'd have to cast the numeric value to use Short.valueOf
)
Note that the add method is generically typed boolean add(E o)
so in your case of Set the add method will take a short, whereas the remove method is not generically typed boolean remove(Object o)
so i - 1
autoboxes to a Integer. For any value of i new Short(i).equals(new Integer(i))
will always be false.
Note that if you try s.add(i - 1);
you will get a compiler error because i - 1
becomes an instance of Integer and the types Integer and Short do not match.
精彩评论