«1. Обзор

В этом уроке мы узнаем, как построить список, содержащий примитивные целочисленные значения.

Мы рассмотрим решения, использующие ядро ​​Java и внешние библиотеки.

2. Автоупаковка

В Java аргументы универсального типа должны быть ссылочными типами. Это означает, что мы не можем сделать что-то вроде List\u003cint\u003e.

Вместо этого мы можем использовать List\u003cInteger\u003e и использовать автоупаковку. Автоупаковка помогает нам использовать интерфейс List\u003cInteger\u003e так, как если бы он содержал примитивные значения типа int. Под капотом это по-прежнему набор объектов, а не примитивов.

Основное решение Java — это просто настройка, позволяющая использовать примитивы с универсальными коллекциями. Кроме того, это связано со стоимостью конвертации упаковки и распаковки.

Однако в Java есть другие варианты и дополнительные сторонние библиотеки, которые мы можем использовать. Давайте посмотрим, как их использовать ниже.

3. Использование Stream API

Часто нам не столько нужно создавать список, сколько просто работать с ним.

В этих случаях вместо создания списка можно использовать Stream API Java 8. Класс IntSream предоставляет последовательность примитивных элементов типа int, которая поддерживает последовательные агрегатные операции.

Давайте кратко рассмотрим пример:

IntStream stream = IntStream.of(5, 10, 0, 2, -8);

Статический метод IntStream.of() возвращает последовательный IntStream.

Точно так же мы можем создать IntStream из существующего массива целых чисел:

int[] primitives = {5, 10, 0, 2, -8};
IntStream stream = IntStream.of(primitives);

Кроме того, мы можем применить стандартные операции Stream API для итерации, фильтрации и агрегирования целых чисел. Например, мы можем вычислить среднее значение положительных значений int:

OptionalDouble average = stream.filter(i -> i > 0).average();

Самое главное, что при работе с потоками не используется автобокс.

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

4. Использование Trove

Trove — это высокопроизводительная библиотека, предоставляющая примитивные коллекции для Java.

Чтобы настроить Trove с Maven, нам нужно включить зависимость trov4j в наш pom.xml:

<dependency>
    <groupId>net.sf.trove4j</groupId>
    <artifactId>trove4j</artifactId>
    <version>3.0.2</version>
</dependency>

С помощью Trove мы можем создавать списки, карты и наборы.

Например, существует интерфейс TIntList с его реализацией TIntArrayList для работы со списком значений int:

TIntList tList = new TIntArrayList();

Несмотря на то, что TIntList не может напрямую реализовать List, его методы очень сопоставимы. Другие решения, которые мы обсуждаем, следуют аналогичному шаблону.

Самым большим преимуществом использования TIntArrayList является увеличение производительности и потребления памяти. Никакой дополнительной упаковки/распаковки не требуется, так как данные хранятся внутри массива int[].

5. Использование Fastutil

Другой высокопроизводительной библиотекой для работы с примитивами является Fastutil. Давайте добавим зависимость fastutil:

<dependency>
    <groupId>it.unimi.dsi</groupId>
    <artifactId>fastutil</artifactId>
    <version>8.1.0</version>
</dependency>

Теперь мы готовы ее использовать:

IntArrayList list = new IntArrayList();

Конструктор по умолчанию IntArrayList() внутренне создает массив примитивов с емкостью по умолчанию 16. В том же vein, мы можем инициализировать его из существующего массива:

int[] primitives = new int[] {5, 10, 0, 2, -8};
IntArrayList list = new IntArrayList(primitives);

6. Использование Colt

Colt — это высокопроизводительная библиотека с открытым исходным кодом для научных и технических вычислений. Пакет cern.colt содержит списки изменяемого размера, содержащие примитивные типы данных, такие как int.

Во-первых, давайте добавим зависимость colt:

<dependency>
    <groupId>colt</groupId>
    <artifactId>colt</artifactId>
    <version>1.2.0</version>
</dependency>

Список примитивов, который предлагает эту библиотеку, cern.colt.list.IntArrayList:

cern.colt.list.IntArrayList coltList = new cern.colt.list.IntArrayList();

Начальная емкость по умолчанию равна десяти.

7. Использование Guava

Guava предоставляет несколько способов взаимодействия между примитивными массивами и API коллекций. В пакете com.google.common.primitives есть все классы для размещения примитивных типов.

Например, класс ImmutableIntArray позволяет создать неизменяемый список элементов типа int.

Предположим, у нас есть следующий массив значений int:

int[] primitives = new int[] {5, 10, 0, 2};

Мы можем просто создать список с массивом:

ImmutableIntArray list = ImmutableIntArray.builder().addAll(primitives).build();

Кроме того, он предоставляет список API со всеми стандартными методами, которые мы ожидать.

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

В этой быстрой статье мы показали несколько способов создания списков с примитивными целыми числами. В наших примерах мы использовали библиотеки Trove, Fastutil, Colt и Guava.

Как обычно, полный код этой статьи доступен на GitHub.