Reputation: 147
public class Short {
public static void main(String[] args) {
Set s = new HashSet();
for(short i = 0; i < 100; i++) {
s.add(i);
s.remove(i-1);
}
System.out.print(s.size());
}
}
Can anyone tell me why it prints 100 instead of 1?
Upvotes: 4
Views: 199
Reputation: 347234
There seems to be some auto boxing going on...that is Java is automatically converting between Object
and primitive...
If I ... rename your class, use Short
instead of short
in the initialisation of the Set
and then use...
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());
It will print 100
...but why?
To answer that, we need to take a closer look at the remove
method...
Set#remove(Object o)
expects an Object
, not the generic type like add
, but an actual Object
...when you do i - 1
, Java assumes that 1
is an int
and automatically scales the types up and auto boxes it as new Integer(i - 1)
...which clear does not exist within the set
(you don't have any Integer
objects!)
However, if we change s.remove(i - 1);
to s.remove((short)(i - 1));
, we force the conversion of the value back to short
which then gets autoboxed as new Short(i - 1)
, which does exist in your set and the end result is it will now print 1
...
Simple ;)
Upvotes: 10
Reputation: 2907
Upon running this code, I found that, after converting your primitive generic to java.lang.Short
, the problem is when you do i-1
. short
-int
returns int
, therefore the remove
operation tries to remove an Integer
from s
. int
and short
, and, respectively, Integer
and Short
are very different.
Upvotes: 2