Java HashSet и Короткий тип данных, несовместимость?

Выполнение этого кода:

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

    }

}

Распечатает значение 100.

Почему это печатает это значение?

5
задан IAdapter 7 June 2010 в 10:10
поделиться

4 ответа

s.remove(i - 1);

Строка выше попытается удалить объекты Integer из набора, потому что все целочисленные вычисления в Java имеют результаты int (или long). Поскольку набор содержит объекты Short, метод remove() не будет иметь никакого эффекта.

Это (и подобные проблемы) является основной причиной, по которой практически никогда не следует использовать short (и, тем более, Short). Использование реализации Set для содержания автобоксированных чисел приводит к огромным (легко 1000%) накладным расходам, поэтому бессмысленно пытаться сэкономить место, используя Short, а не Integer.

10
ответ дан 18 December 2019 в 09:47
поделиться

Проблема в том, что remove(i-1) вызывает метод remove с объектом Integer, так как i-1 имеет тип int (который автобоксируется в Integer).

Чтобы убедиться, что вы вызываете remove с объектом Short, используйте следующее:

s.remove((short) (i - 1));
7
ответ дан 18 December 2019 в 09:47
поделиться

Обратите внимание, что метод добавления обычно имеет тип boolean add (E o) , поэтому в вашем случае Set метод добавления займет короткое время, тогда как метод удаления не имеет общего типа boolean remove (Объект o) , поэтому i - 1 автоматически преобразуется в целое число. Для любого значения i new Short (i) .equals (new Integer (i)) всегда будет ложным.

Обратите внимание, что если вы попробуете s.add (i - 1); , вы получите ошибку компилятора, потому что i - 1 становится экземпляром Integer, а типы Integer и Short не совпадает.

0
ответ дан 18 December 2019 в 09:47
поделиться

Тип i - 1 - int , поэтому он автоматически преобразуется в целое число.

Обычно можно ожидать, что универсальная коллекция предотвратит выполнение операций с аргументами неправильного типа, но интерфейс для Set немного нечеткий.

Поскольку метод remove из Set принимает объект , а не E , компилятор не предупреждает вы, что удаляете другой тип, отличный от того, что содержит набор.

Чтобы заставить его быть Short , приведите числовое значение к (short) . (преобразование в (Short) не допускается, и вам придется преобразовать числовое значение, чтобы использовать Short.valueOf )

0
ответ дан 18 December 2019 в 09:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: