A Java Puzzle
During the presentation by William Pugh at JavaOne, he mentioned this interesting puzzle
public class Puzzle { 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.println("Size of set = " + s.size()); } }
Now the question is, what will the above program print out as size of set? Options are
- 1
- 100
- Throws Exception
- None of above
My answer at first was option (1) as we are adding and removing everything except 99. But as this is a puzzle the answer should be different. Here goes the explanation ….
The answer is option (2). The reason is that the statement s.remove(i-1) is operating on integer. This might look strange but in Java 1 is int and even if i is short (i-1) is int. And due to autoboxing (i-1) becomes Integer object. Even though set s takes Short as the type when declared, remove method on an object of Set class takes in an Object and not the generic type. So the result is we are removing an element which isn’t there in the set. So we are just keeping on adding all the 100 elements but removing none. Hence the answer (2).
So to correct the above program to get the expected result i.e., option (1), we need to cast (i-1) to short and then remove from the set.
But the interesting question is how to detect such kind of bugs. There comes the use of FindBugs a static code analyzer which is very slick.
Followed your post from your comment
Interesting insight.
Look at the following code:
List t = new ArrayList();
t.add(1);
t.add(2);
System.out.println(”Size of set = ” + t.indexOf(2));
In here the output is :
“Size of set = 1″
What could be an explanation for this?