Коллекции Java. Почему нет примитивных типов?

Возможное дублирование:
сохранение примитивных значений в коллекция java?

В моем учебнике по Java говорится, что элементы коллекции, например ArrayList, не могут быть примитивными типами. Есть причина для этого? Я имею в виду, что кто-то в Sun решил это сделать или есть какие-то препятствия для этого? Я понимаю, что мой пример частично отвечает на мой вопрос, поскольку ArrayList требует объекта, а примитивы не являются объектами. Но тогда я думаю, почему у них тоже не может быть примитивных типов?


person Community    schedule 04.01.2011    source источник


Ответы (6)


есть ли какие-то препятствия для этого?

Вы можете написать почти идентичные версии ArrayList, которые были специально созданы для хранения одного из неклассовых типов, например IntegerArrayList и так далее. Барьер против этого заключается в том, что таких классов будет взрывной рост, поскольку вы умножите количество примитивных типов на количество типов коллекций. Это было исключено, чтобы сохранить управляемость стандартной структуры сбора данных.

Чтобы решить эту проблему более аккуратно на языке, вам потребуются универсальные шаблоны, которые позволят примитивным типам выступать в качестве параметров типа и улучшат взаимодействие между массивами и универсальными шаблонами.

person Daniel Earwicker    schedule 04.01.2011

Хранение развернутых примитивов значительно усложнило бы код коллекций. В то время как с оболочками (Integer для int и т. Д.) Код довольно прост. Вот уже несколько лет Java поддерживает «автоматическую упаковку», что означает, что если вы дадите int вместо ожидаемого Integer, int будет заключен в экземпляр Integer для вас (и наоборот).

person T.J. Crowder    schedule 04.01.2011

Есть объекты, называемые «оболочками», которые представляют все примитивные типы. Например, есть класс с именем Integer, который поддерживает int. Вы можете использовать примитивные оболочки для хранения значений в коллекции.

Проблема с примитивными типами (по крайней мере, до Java 5) заключается в том, что они не расширяются от базового класса Object. Все коллекции должны указывать класс для всех используемых ими методов - и они указывают Object, поскольку Object является базой всех классов.

Начиная с Java 5, вы обнаружите, что Java будет неявно переключаться между примитивом и соответствующим ему классом-оболочкой, когда вам это нужно. Это означает, что вы можете добавить в коллекцию int, double и т. Д. ВМ автоматически обернет примитив в класс-оболочку для вас и поместит оболочку в коллекцию.

person Jonathan B    schedule 04.01.2011
comment
Проблема с примитивными типами (по крайней мере, до Java 5) ... и более поздних версий тоже. Хотя теперь есть автоматическая упаковка, для примитивных типов по-прежнему нет общего базового класса. - person Daniel Earwicker; 04.01.2011

В настоящее время единственный способ хранить примитивы непосредственно в коллекции - иметь коллекцию для каждого примитивного типа, например. TIntArrayList.

Вы, вероятно, обнаружите, что, хотя ArrayList медленнее, чем при использовании примитивов, он достаточно быстр для 90 +% случаев использования.

person Peter Lawrey    schedule 04.01.2011

Прочтите эту статью в Википедии. Это может помочь: http://en.wikipedia.org/wiki/Object_type_(object-oriated_programming)#Autoboxing

В информатике тип объекта (также известный как объект-оболочка) - это тип данных, который используется в объектно-ориентированном программировании для обертывания не-объектного типа, чтобы он выглядел как динамический объект.

Некоторые объектно-ориентированные языки программирования делают различие между ссылочными типами и типами значений, часто называемыми объектами и не-объектами на платформах, где не существуют сложные типы значений, по таким причинам, как эффективность времени выполнения и синтаксические или семантические проблемы. Например, в Java есть классы-оболочки-примитивы, соответствующие каждому примитивному типу: Integer и int, Character и char, Float и float и т. Д. Такие языки, как C ++, практически не имеют понятия ссылочного типа; таким образом, использование типа объекта не представляет особого интереса.

Упаковка - это процесс помещения примитивного типа в объект, чтобы этот примитив можно было использовать в качестве ссылочного объекта. Например, списки могут иметь определенные методы, а массивы могут не иметь, но для списка также может потребоваться что все его члены являются динамическими объектами. В этом случае добавленная функциональность списка может быть недоступна для простого массива чисел. В качестве более конкретного примера в Java LinkedList может изменять свой размер, но массив должен иметь фиксированный размер. Кто-то может пожелать иметь LinkedList целых чисел, но класс LinkedList перечисляет только ссылки на динамические объекты - он не может перечислять примитивные типы, которые являются типами значений.

Чтобы обойти это, целые числа можно объединить в целые числа, которые являются динамическими объектами, а затем добавить в связанный список целых чисел. (Используя универсальные параметризованные типы, представленные в J2SE 5.0, этот тип представлен как LinkedList.) С другой стороны, C # не имеет примитивных классов-оболочек, но позволяет упаковывать любой тип значения, возвращая общую ссылку на объект.

Упакованный объект всегда является копией объекта значения и обычно неизменяем. Распаковка объекта также возвращает копию сохраненного значения. Обратите внимание, что повторная упаковка и распаковка объектов может серьезно повлиять на производительность, поскольку она динамически выделяет новые объекты, а затем делает их доступными для сборки мусора.

person Pedro Loureiro    schedule 04.01.2011

Проблема с производительностью - одна из проблем, поскольку для этого нам нужна автоматическая упаковка. Также для некоторых структур может быть полезно иметь нулевые значения.

person Mite Mitreski    schedule 04.01.2011