Узнайте о поддержке примитивных коллекций в Eclipse Collections.

Пороки бокса на Яве

В Java есть восемь примитивных типов. Это boolean, byte, char, short, int, float, long и double. Каждый примитивный тип имеет соответствующую оболочку объекта. Это Boolean, Byte, Character, Short, Integer, Float, Long и Double. Упаковка - это процесс принятия примитивного значения и сохранения его в экземпляре соответствующего ему типа оболочки. Autoboxing - это функция, добавленная в Java 5. Autoboxing позволяет автоматически заключать примитивное значение в экземпляр соответствующего ему класса оболочки, не требуя от разработчиков явного написания какого-либо кода для выполнения упаковки.

Для получения дополнительной информации об автобоксовке и распаковке, пожалуйста, обратитесь к разделу руководства по Java Автобоксинг и распаковка.

Измерение размеров объектов в JVM - хорошая статья и введение в использование Java Object Layout, который является проектом OpenJDK Code Tools.

Почему бокс - зло?

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

Спасибо, пожалуйста, никаких скрытых ящиков!

Коллекции Eclipse помогает предотвратить создание разработчиками скрытых ящиков в куче Java, предоставляя им полный контроль с помощью полного набора примитивных коллекций. Сегодня в Eclipse Collections есть несколько примитивных структур данных, которые работают со всеми восемью примитивными типами.

В API есть поддержка преобразования между коллекциями объектов и примитивов.

Подобно реализации в коллекциях объектов, возвращаемые типы являются ковариантными и специализированными по подтипам. Я продемонстрирую это, показав примеры API как для изменяемых, так и для неизменяемых типов.

Визуализация примитивной иерархии типов коллекции

Генерация кода во время сборки

Если восемь раз воспроизвести и поддерживать исходный код приведенных выше диаграмм кажется невыполнимой задачей, вы будете правы. Хитрость в том, что мы кодируем примитивные типы коллекций из файлов шаблонов. Eclipse Collections использует StringTemplate для генерации большей части исходного кода Java для своих примитивных коллекций. Это происходит во время сборки. Таким образом, вы не увидите исходные файлы .java для примитивных коллекций в GitHub. Однако вы увидите шаблоны с расширением .stg в модуле eclipse-collections-code-generator.

Покажи мне код

Я приведу примеры всех примитивных структур данных для одного примитивного типа - int. Существует очень богатый API для сбора примитивов, и я продемонстрирую немало методов в коде. Будьте готовы прокрутить, так как примеров очень много.

Оглавление

Щелкните ссылку ниже, чтобы перейти к разделу. Щелкните ссылку TOC внизу каждого раздела, чтобы вернуться сюда.

Примитивный список

Примитивные List реализации в Eclipse Collections основаны на массивах. Есть как изменяемые, так и неизменяемые списки примитивов. Следующий код продемонстрирует API, доступные для изменяемых и неизменяемых типов. В иерархии пакетов появится шаблон, который упростит обнаружение различных типов в среде IDE.

Примечание. IntInterval - это ImmutableIntList.

ТОС

Примитивный набор

Примитивные реализации Set в коллекциях Eclipse основаны на массивах и используют открытую адресацию. Есть как изменяемые, так и неизменяемые примитивные наборы. Следующий код продемонстрирует API, доступные для изменяемых и неизменяемых наборов.

ТОС

Примитивная сумка

Примитивные реализации Bag в Коллекциях Eclipse поддерживаются примитивом Maps. Например, IntBag будет поддерживаться IntIntMap. где первый int - это тип Bag, а второй int - количество каждого значения в Bag. Существуют как изменяемые, так и неизменяемые примитивные пакеты. Следующий код продемонстрирует API-интерфейсы, доступные для изменяемых и неизменяемых пакетов.

ТОС

Примитивный стек

Примитивные реализации Stack в коллекциях Eclipse поддерживаются примитивным массивом. Существуют как изменяемые, так и неизменяемые примитивные стеки. Следующий код продемонстрирует API-интерфейсы, доступные для изменяемых и неизменяемых стеков.

Примечание. Stack не является Collection, поэтому Stack не имеет дополнительных методов изменения, таких как add, addAll, remove, removeAll или retainAll. В коллекциях Eclipse у Stack есть богатый итеративный набор методов (например, select, reject, collect и т. Д.).

ТОС

Примитивная карта

Примитивные Map реализации в Eclipse Collections поддерживают все комбинации типов ключей и типов значений. В случае, когда типы ключей и значений совпадают, и ключи, и значения хранятся в одном массиве. В случаях, когда типы ключа и значения различаются, они будут храниться в отдельных массивах. Есть как изменяемые, так и неизменяемые примитивные карты. Следующий код продемонстрирует API, доступные на изменяемых и неизменяемых картах.

Примечание. Map типов в коллекциях Eclipse имеют Iterable значение. Таким образом, IntIntMap также является IntIterable и поддерживает полный набор методов, доступных на IntIterable.

ТОС

Примитивный ленивый итерабельный

Каждая примитивная коллекция может вернуть себе ленивое представление, вызвав asLazy. Следующий код покажет некоторые из ленивых операций, доступных на LazyIntInterable.

ТОС

Примитивные синхронизированные коллекции

Каждая изменяемая примитивная коллекция может возвращать синхронизированное представление о себе, вызывая asSynchronized. Синхронизированные коллекции небезопасно использовать с iterator без явной блокировки. Однако существует большое количество атомарных операций, доступных для типа, которые принимают блокировки внутри методов.

ТОС

Примитивные неизменяемые коллекции

Каждая изменяемая примитивная коллекция может вернуть неизменяемое представление о себе, вызвав asUnmodifiable. Неизменяемые коллекции небезопасно использовать с методами изменения, такими как add, remove и т. Д., Поскольку они будут генерировать UnsupportedOperationException. Однако в коллекциях доступно большое количество методов, доступных только для чтения.

ТОС

Примитивная строка

Eclipse Collections имеет три простых String адаптера - CharAdapter, CodePointAdapter, CodePointList. Эти типы предоставляют богатые примитивные протоколы для символов или кодовых точек в String. CharAdapter и CodePointAdapter - чистые взгляды на String. CodePointList фактически кэширует кодовые точки из String в ImmutableIntList.

ТОС

Затраты на память

Упаковка примитивов в оболочки требует значительных затрат памяти. В следующей таблице показана сравнительная стоимость памяти для хранения 1 миллиона значений int как в примитивных, так и в упакованных структурах данных. Я могу потратить некоторое время на то, чтобы поместить это в диаграмму, но подумал, что рано поделюсь этими необработанными сравнениями вместе с кодом, который я использовал для их вычисления.

Примечание. Самый простой сборщик мусора - это мусор, который никогда не создавался.

В ожидании Валгаллы

Я в восторге от обещания проекта Valhalla для Java. Возможно, вы ждете, пока проект Valhalla улучшит производительность кода, который вы пишете. Я искренне хотел бы дождаться Валгаллы. Это, вероятно, избавило бы меня и многих других, кто работает над коллекциями Eclipse и другими примитивными библиотеками коллекций, от большого количества работы. К сожалению, ждать появления расширенных возможностей в будущей версии языка программирования - вариант не для всех.

Мы добавили примитивные коллекции с богатым API в Коллекции Eclipse почти девять лет назад. Мы увидели выдающиеся преимущества. Мы надеемся, что признание этих преимуществ помогло сохранить фокус и развитие JEP 218: обобщения над примитивными типами.

Я рада, что мы не подождали. Уроки, которые мы извлекли и продолжаем усваивать в примитивном пространстве коллекций, могут помочь в разработке и разработке проекта Valhalla.

Мысли о недостающих структурах данных в Java

Даже после того, как мы доберемся до Валгаллы на Java, в Java будет много отсутствующих структур данных. Я писал о необходимости возрождения пространства коллекций Java в прошлом году. Возможности обширной библиотеки коллекций Java огромны. Это очевидно по размеру Коллекций Затмения. Несмотря на это, мы продолжим работу с коллекциями Eclipse и будем помогать развивать пространство коллекций Java.

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

Особая благодарность Сирише Прата за вычитку черновой версии этого блога.

Я руководитель проекта и ответственный за проект OSS Коллекции Eclipse в Eclipse Foundation. Eclipse Collections открыта для пожертвований. Если вам нравится библиотека, вы можете сообщить нам об этом, отметив ее на GitHub.

Другие статьи по программированию на Java, которые могут вам понравиться:
Полный план развития Java-разработчика
10 вещей, которые должен выучить Java-программист
10 языков программирования, которые вы можете изучить
10 инструментов, которые должен знать каждый Java-разработчик
10 причин изучать языки программирования Java в 2021 году
Мои любимые бесплатные курсы программирования для начинающих
10 бесплатных Курсы по структуре данных и алгоритмам
7 лучших курсов по структуре данных и алгоритмам для начинающих
50+ вопросов для интервью по структуре данных и алгоритмам