Перейти к основному содержимому

Преобразование массива примитивов в массив объектов

· 3 мин. чтения

1. Введение

В этом коротком руководстве мы покажем, как преобразовать массив примитивов в массив объектов и наоборот.

2. Проблема

Допустим, у нас есть массив примитивов, таких как int[] , и мы хотели бы преобразовать его в массив объектов Integer[] . Мы могли бы интуитивно попробовать приведение:

Integer[] integers = (Integer[])(new int[]{0,1,2,3,4});

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

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

3. Итерация

Давайте посмотрим, как мы можем использовать автоупаковку в итерации.

Во-первых, давайте преобразуем примитивный массив в массив объектов:

int[] input = new int[] { 0, 1, 2, 3, 4 };
Integer[] expected = new Integer[] { 0, 1, 2, 3, 4 };

Integer[] output = new Integer[input.length];
for (int i = 0; i < input.length; i++) {
output[i] = input[i];
}

assertArrayEquals(expected, output);

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

Integer[] input = new Integer[] { 0, 1, 2, 3, 4 };
int[] expected = new int[] { 0, 1, 2, 3, 4 };

int[] output = new int[input.length];
for (int i = 0; i < input.length; i++) {
output[i] = input[i];
}

assertArrayEquals(expected, output);

Как мы видим, это совсем не сложно, но более читаемое решение, такое как Stream API, могло бы лучше удовлетворить наши потребности.

4. Потоки

Начиная с Java 8, мы можем использовать Stream API для написания плавного кода.

Во-первых, давайте посмотрим, как упаковать элементы примитивного массива:

int[] input = new int[] { 0, 1, 2, 3, 4 };
Integer[] expected = new Integer[] { 0, 1, 2, 3, 4 };

Integer[] output = Arrays.stream(input)
.boxed()
.toArray(Integer[]::new);

assertArrayEquals(expected, output);

Обратите внимание на параметр Integer[]::new в методе toArray . Без этого параметра поток вернул бы Object[] вместо Integer[] .

Затем, чтобы преобразовать их обратно, мы будем использовать метод mapToInt вместе с методом распаковки Integer :

Integer[] input = new Integer[] { 0, 1, 2, 3, 4 };
int[] expected = new int[] { 0, 1, 2, 3, 4 };

int[] output = Arrays.stream(input)
.mapToInt(Integer::intValue)
.toArray();

assertArrayEquals(expected, output);

С помощью Stream API мы создали более удобочитаемое решение, но если мы все еще хотим, чтобы оно было более кратким, мы могли бы попробовать библиотеку, например Apache Commons.

5. Апач Коммонс

Во-первых, давайте добавим библиотеку Apache Commons Lang в качестве зависимости:

<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>

Затем, чтобы преобразовать массив примитивов в его упакованный аналог, воспользуемся методом ArrayUtils.toObject :

int[] input = new int[] { 0, 1, 2, 3, 4 };
Integer[] expected = new Integer[] { 0, 1, 2, 3, 4 };

Integer[] output = ArrayUtils.toObject(input);

assertArrayEquals(expected, output);

Наконец, чтобы обратно преобразовать упакованные элементы в примитивы, воспользуемся методом ArrayUtils.toPrimitives :

Integer[] input = new Integer[] { 0, 1, 2, 3, 4 };
int[] expected = new int[] { 0, 1, 2, 3, 4 };

int[] output = ArrayUtils.toPrimitive(input);

assertArrayEquals(expected, output);

Библиотека Apache Commons Lang предоставляет лаконичное и простое в использовании решение нашей проблемы, но с затратами на добавление зависимости.

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

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

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