Как преобразовать ArrayList, содержащий целые числа, в примитивный массив int? - PullRequest
237 голосов
/ 05 апреля 2009

Я пытаюсь преобразовать ArrayList, содержащий объекты Integer, в примитив int [] со следующим фрагментом кода, но он выдает ошибку времени компиляции. Можно ли конвертировать в Java?

List<Integer> x =  new ArrayList<Integer>();
int[] n = (int[])x.toArray(int[x.size()]);

Ответы [ 12 ]

204 голосов
/ 05 апреля 2009

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

public static int[] convertIntegers(List<Integer> integers)
{
    int[] ret = new int[integers.size()];
    for (int i=0; i < ret.length; i++)
    {
        ret[i] = integers.get(i).intValue();
    }
    return ret;
}

(Обратите внимание, что это вызовет исключение NullPointerException, если либо integers, либо какой-либо элемент внутри него равен null.)

РЕДАКТИРОВАТЬ: Согласно комментариям, вы можете использовать итератор списка, чтобы избежать неприятных затрат с такими списками, как LinkedList:

public static int[] convertIntegers(List<Integer> integers)
{
    int[] ret = new int[integers.size()];
    Iterator<Integer> iterator = integers.iterator();
    for (int i = 0; i < ret.length; i++)
    {
        ret[i] = iterator.next().intValue();
    }
    return ret;
}
167 голосов
/ 16 мая 2014

Если вы используете , есть и другой способ сделать это.

int[] arr = list.stream().mapToInt(i -> i).toArray();

Что он делает:

  • получение Stream<Integer> из списка
  • получение IntStream путем сопоставления каждого элемента с самим собой (функция идентификации), распаковка значения int, удерживаемого каждым объектом Integer (выполняется автоматически после Java 5)
  • получение массива int путем вызова toArray

Вы также можете явно вызвать intValue через ссылку на метод, т. Е.

int[] arr = list.stream().mapToInt(Integer::intValue).toArray();

Также стоит упомянуть, что вы можете получить NullPointerException, если у вас есть ссылка null в списке. Этого можно легко избежать, добавив условие фильтрации в конвейер потока следующим образом:

                       //.filter(Objects::nonNull) also works
int[] arr = list.stream().filter(i -> i != null).mapToInt(i -> i).toArray();

Пример: * * тысяча тридцать-один

List<Integer> list = Arrays.asList(1, 2, 3, 4);
int[] arr = list.stream().mapToInt(i -> i).toArray(); //[1, 2, 3, 4]

list.set(1, null); //[1, null, 3, 4]
arr = list.stream().filter(i -> i != null).mapToInt(i -> i).toArray(); //[1, 3, 4]
60 голосов
/ 05 апреля 2009

Apache Commons имеет класс ArrayUtils, у которого есть метод toPrimitive (), который делает именно это.

import org.apache.commons.lang.ArrayUtils;
...
    List<Integer> list = new ArrayList<Integer>();
    list.add(new Integer(1));
    list.add(new Integer(2));
    int[] intArray = ArrayUtils.toPrimitive(list.toArray(new Integer[0]));

Однако, как показал Джон, довольно легко сделать это самостоятельно, вместо использования внешних библиотек.

56 голосов
/ 18 декабря 2011

Google Guava

Google Guava предоставляет удобный способ сделать это, позвонив по номеру Ints.toArray.

List<Integer> list = ...;
int[] values = Ints.toArray(list);
41 голосов
/ 03 апреля 2011

Я считаю, что итерация с использованием итератора List является лучшей идеей, поскольку list.get(i) может иметь низкую производительность в зависимости от реализации List:

private int[] buildIntArray(List<Integer> integers) {
    int[] ints = new int[integers.size()];
    int i = 0;
    for (Integer n : integers) {
        ints[i++] = n;
    }
    return ints;
}
6 голосов
/ 01 февраля 2010

используя Доллар должно быть довольно просто:

List<Integer> list = $(5).toList(); // the list 0, 1, 2, 3, 4  
int[] array = $($(list).toArray()).toIntArray();

Я планирую улучшить DSL, чтобы удалить промежуточный toArray() вызов

3 голосов
/ 29 августа 2013

Если вы используете Eclipse Collections , вы можете использовать метод collectInt() для переключения с контейнера объекта на примитивный контейнер int.

List<Integer> integers = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
MutableIntList intList =
  ListAdapter.adapt(integers).collectInt(i -> i);
Assert.assertArrayEquals(new int[]{1, 2, 3, 4, 5}, intList.toArray());

Если вы можете конвертировать ArrayList в FastList, вы можете избавиться от адаптера.

Assert.assertArrayEquals(
  new int[]{1, 2, 3, 4, 5},
  Lists.mutable.with(1, 2, 3, 4, 5)
    .collectInt(i -> i).toArray());

Примечание: Я коммиттер для коллекций Eclipse.

2 голосов
/ 30 апреля 2010

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

Просто зайдите с Apache Commons

1 голос
/ 13 августа 2015

Вы можете просто скопировать его в массив:

int[] arr = new int[list.size()];
for(int i = 0; i < list.size(); i++) {
    arr[i] = list.get(i);
}

Не слишком необычно; но, эй, это работает ...

0 голосов
/ 14 февраля 2016

Этот сегмент кода работает для меня, попробуйте это:

Integer[] arr = x.toArray(new Integer[x.size()]);

Стоит упомянуть, что ArrayList должен быть объявлен так:

ArrayList<Integer> list = new ArrayList<>();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...