Почему Java-коллекции не могут напрямую хранить типы примитивов?

Коллекции Java хранят только объекты, а не примитивные типы; однако мы можем хранить классы-оболочки.

Почему это ограничение?

Ответ 1

Это было дизайнерское решение для Java, а другое - ошибочное. Контейнеры хотят, чтобы объекты и примитивы не были получены из Object.

Это одно место, которое разработчики .NET узнали из JVM и реализовали типы значений и генерики, которые во многих случаях устраняют бокс. В CLR универсальные контейнеры могут хранить типы значений как часть базовой структуры контейнера.

Java решила добавить общую поддержку 100% в компилятор без поддержки JVM. JVM - это то, что он есть, не поддерживает объект "non-object". Java-дженерики позволяют вам притворяться, что нет обертки, но вы по-прежнему платите цену за бокс. Это ВАЖНО для определенных классов программ.

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

Хорошее объяснение SO о боксе: Почему некоторые языки нуждаются в боксе и распаковке?

И критика Java-дженериков: Почему некоторые утверждают, что реализация дженериков Java плоха?

В защите Java легко смотреть назад и критиковать. JVM выдержала испытание временем и во многих отношениях является хорошей конструкцией.

Ответ 2

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

Вы можете это сделать, конечно, просто посмотрите GNU Trove, Apache Commons Primitives или HPPC.

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

Ответ 3

Это комбинация двух фактов:

  • примитивные типы Java не являются ссылочными типами (например, int не является Object)
  • В Java реализованы генераторы с использованием стирания типов ссылочных типов (например, List<?> на самом деле List<Object> во время выполнения)

Так как оба они верны, общие коллекции Java не могут хранить примитивные типы напрямую. Для удобства вводится автобоксирование, позволяющее автоматически вводить примитивные типы в качестве ссылочных типов. Не ошибитесь, но коллекции все равно хранят ссылки на объекты независимо.

Можно ли это избежать? Может быть.

  • Если int является Object, тогда нет необходимости в типах полей.
  • Если генераторы не выполняются с использованием стирания типа, тогда для параметров типа могут использоваться примитивы.

Ответ 4

Существует концепция автоматического бокса и автоматического распаковки. Если вы попытаетесь сохранить int в List<Integer>, компилятор Java автоматически преобразует его в Integer.

Ответ 5

На самом деле это не ограничение?

Рассмотрим, хотите ли вы создать коллекцию, в которой хранились примитивные значения. Как бы вы могли написать коллекцию, которая может хранить либо int, либо float, либо char? Скорее всего, у вас будет множество коллекций, поэтому вам понадобится intlist и charlist и т.д.

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

Ответ 6

Я думаю, что мы могли бы увидеть прогресс в этом пространстве в JDK, возможно, в Java 10 на основе этого JEP - http://openjdk.java.net/jeps/218.

Если вы хотите избежать примитивов бокса в коллекциях сегодня, есть несколько сторонних альтернатив. В дополнение к ранее упомянутым сторонним опциям есть также Eclipse Collections, FastUtil и Koloboke.

Сравнение примитивных карт также было опубликовано некоторое время назад с заголовком: Большой обзор HashMap: JDK, FastUtil, Goldman Sachs, HPPC, Koloboke, Trove. Библиотека GS Collections (Goldman Sachs) была перенесена в Eclipse Foundation и теперь является коллекцией Eclipse.

Ответ 7

Основная причина - стратегия дизайна java. ++ 1) для коллекций требуются объекты для манипуляции, а примитивы не выводятся из объекта, поэтому это может быть другой причиной. 2) Java-примитивные типы данных не являются ссылочным типом для ex. int не является объектом.

Преодолеть: -

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