简体   繁体   中英

Why does this code print 100 instead of 1?

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?

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM