简体   繁体   中英

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.

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