Рубрики
Без рубрики

Карта примитивов в Java

Узнайте, как создать карту примитивов Java с помощью популярных сторонних библиотек

Автор оригинала: baeldung.

1. Обзор

В этом уроке мы узнаем, как построить карту с примитивными ключами и значениями.

Как мы знаем, основные карты Java не позволяют хранить примитивные ключи или значения. Вот почему мы представим некоторые внешние сторонние библиотеки, которые предоставляют примитивные реализации карт.

2. Коллекции Eclipse

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

2.1. Изменяемые и неизменяемые карты

Давайте создадим пустую карту, где и ключи, и значения являются примитивными int s. Для этого мы будем использовать класс Intentmaps factory:

MutableIntIntMap mutableIntIntMap = IntIntMaps.mutable.empty();

Класс Intent maps factory – это наиболее удобный способ создания примитивных карт . Это позволяет нам создавать как изменяемые, так и неизменяемые экземпляры нужного типа карты. В нашем примере мы создали изменяемый экземпляр Int Int Map . Аналогично, мы можем создать неизменяемый экземпляр, просто заменив вызов Intentmaps.mutable static factory на IntIntMaps.immutable :

ImmutableIntIntMap immutableIntIntMap = IntIntMaps.immutable.empty();

Итак, давайте добавим пару ключ-значение к нашей изменяемой карте:

mutableIntIntMap.addToValue(1, 1);

Аналогично, мы можем создавать смешанные карты со ссылочными и примитивными парами ключ-значение типа. Давайте создадим карту с Строкой ключами и двойными значениями:

MutableObjectDoubleMap dObject = ObjectDoubleMaps.mutable.empty();

Здесь мы использовали класс Object Double Maps factory для создания изменяемого экземпляра для Mutable Object Double Map .

Теперь давайте добавим несколько записей:

dObject.addToValue("price", 150.5);
dObject.addToValue("quality", 4.4);
dObject.addToValue("stability", 0.8);

2.2. Примитивное дерево API

В коллекциях Eclipse есть базовый интерфейс под названием PrimitiveIterable. Это базовый интерфейс для каждого из примитивных контейнеров библиотеки. Все они называются Примитивный тип Итерационный , где Примитивный тип может быть Int, Long , Short , Byte , Char , Float , Double или Boolean .

Все эти базовые интерфейсы, в свою очередь, имеют свое дерево реализаций X Y Map , которое делится на то, является ли карта изменяемой или неизменяемой . В качестве примера, для Int Int Map , у нас есть Изменяемая Int Int Map и Неизменяемая Int Int Map .

Наконец, как мы видели выше, у нас есть интерфейсы , которые охватывают все виды комбинаций типов ключей и значений как для примитивных, так и для объектных значений . Так, например, мы можем иметь IntObjectMap для примитивного ключа со значением Object или ObjectIntMap для его противоположного случая.

3. ПК HP

HP PC – это библиотека, ориентированная на высокую производительность и эффективность памяти. Это означает, что библиотека обладает меньшей абстракцией, чем другие. Однако это имеет преимущество в том, что внутренние органы подвергаются полезным низкоуровневым манипуляциям. Он предоставляет как карты, так и наборы.

3.1. Простой Пример

Давайте начнем с создания карты, которая имеет ключ int и значение long . Использование этого довольно знакомо:

IntLongHashMap intLongHashMap = new IntLongHashMap();
intLongHashMap.put(25, 1L);
intLongHashMap.put(150, Long.MAX_VALUE);
intLongHashMap.put(1, 0L);
        
intLongHashMap.get(150);

HP PC предоставляет карты для всех комбинаций клавиш и значений:

  • Примитивный ключ и примитивное значение
  • Примитивный ключ и значение типа объекта
  • Ключ типа объекта и примитивное значение
  • Как ключ типа объекта, так и значение

Карты объектного типа поддерживают универсальные:

IntObjectOpenHashMap
ObjectIntOpenHashMap

Первая карта имеет примитивный ключ int и значение BigDecimal . Вторая карта имеет Локальную дату для своих ключей и int для своих значений

3.2. Хэш-карты против скаттер-карт

Из-за того, как традиционно реализуются функции хеширования и распределения ключей, при хешировании ключей могут возникать коллизии. В зависимости от того, как распределяются ключи, это может привести к проблемам с производительностью на огромных картах. По умолчанию HP PC реализует решение, которое позволяет избежать этой проблемы.

Однако все еще есть место для карт, которые имеют более простую функцию распределения. Это полезно , если карты используются в качестве таблиц поиска или для подсчета, или если они не требуют большого количества операций записи после загрузки . HHPC предоставляет Карты рассеяния для еще большего повышения производительности.

Все классы карт рассеяния поддерживают то же соглашение об именовании, что и карты, но вместо этого используют слово Scatter :

  • Набор разброса Int
  • Int Int Карта рассеяния
  • Карта рассеяния объектов Int

4. Фастутил

Fastutil -это быстрый и компактный фреймворк , который предоставляет коллекции для конкретных типов, включая карты примитивных типов.

4.1. Краткий пример

Аналогично коллекциям Eclipse и ПК HP. Fastutil также предоставляет типизированные карты ассоциаций от примитива к примитиву и от примитива к объекту.

Давайте создадим int to boolean map:

Int2BooleanMap int2BooleanMap = new Int2BooleanOpenHashMap();

А теперь давайте добавим несколько записей:

int2BooleanMap.put(1, true);
int2BooleanMap.put(7, false);
int2BooleanMap.put(4, true);

Затем мы можем извлечь из него значения:

boolean value = int2BooleanMap.get(1);

4.2. Итерация на Месте

Стандартные коллекции JVM, реализующие интерфейс Iterable , обычно создают новый временный объект итератора на каждом шаге итерации. С огромными коллекциями это может создать проблему сборки мусора.

Fastutil предоставляет альтернативу, которая значительно смягчает эту проблему:

Int2FloatMap map = new Int2FloatMap();
//Add keys here
for(Int2FloatMap.Entry e : Fastutil.fastIterable(map)) {
    //e will be reused on each iteration, so it will be only one object
}

Fastutil также предоставляет fast Для каждого метода . Это займет Потребитель функциональный интерфейс и выполнит лямбда-выражение для каждого цикла:

Int2FloatMap map = new Int2FloatMap();
//Add keys here
Int2FloatMaps.fastForEach(map , e ->  {
    // e is also reused across iterations
});

Это очень похоже на стандартную конструкцию Java foreach :

Int2FloatMap map = new Int2FloatMap();
//Add keys here
map.forEach((key,value) -> {
    // use each key/value entry   
});

5. Заключение

В этой статье мы узнали, как создавать примитивные карты в Java с помощью коллекций Eclipse, HPPC и Fastutil .

Как всегда, пример кода для этой статьи доступен на GitHub .