I wasn\'t sure on how to ask this question. But, what is the different between these 2 lines of code?
Set a = new HashSet();
f
The type of the expression i - 1
is int
because all operands in an integer arithmetic expression are widened to at least int
. Set<Short>
has add(Short)
and remove(Object)
so there's no casting/autoboxing needed on the remove
call. Therefore you are trying to remove Integer
s from a set of Short
s.
Note that for this reason it almost never makes sense to declare a Set<Number>
:
final Set<Number> ns = new HashSet<>();
final short s = 1;
ns.add(s);
ns.add(s+0);
ns.add(s+0L);
System.out.println(ns); // prints [1, 1, 1]
As a bonus round, if you change the set implementation to TreeSet
, the magic disappears and it throws a ClassCastException
, giving away the trick.
Deep down, this issue has to do with the fact that equality is a symmetric relation, which must not distinguish the right hand side from the left hand side. These semantics are impossible to achieve with Java's single-dispatch methods.
The first code snippet removes from a HashSet
of Integers
all the numbers except for 99
because 98
is last number it removes.
The second code snippet is trying to remove an Integer
from a HashSet
of Shorts
, consequently, it does not remove any element.
On the first code snippet, in the statement add(i)
the int
is automatically converted to an Integer
.
On the second code snippet, if you had done the following:
Set<Short> a = new HashSet<Short>();
for (Short i = 0; i < 100; i++) {
a.add(i);
a.remove(i);
}
It would remove all the elements, since you add and remove a Short
. However, because you are trying to remove i - 1
, it will convert i - 1
to an Integer
. Hence, trying to remove an Integer
from a HashSet of Shorts
, which actually leads to no number being removed.
You can't remove Integer from Set of shorts without casting.