Преобразование массива в список в Java - PullRequest
889 голосов
/ 09 апреля 2010

Как мне преобразовать массив в список на Java?

Я использовал Arrays.asList(), но поведение (и подпись) почему-то изменилось с Java SE 1.4.2 (документы теперь в архиве) на 8 и большинство фрагментов, которые я нашел на Интернет использует поведение 1.4.2.

Например:

int[] spam = new int[] { 1, 2, 3 };
Arrays.asList(spam)
  • на 1.4.2 возвращает список, содержащий элементы 1, 2, 3
  • на 1.5.0+ возвращает список, содержащий массив спама

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

Assert.assertTrue(Arrays.asList(spam).indexOf(4) == -1);

Ответы [ 17 ]

1288 голосов
/ 09 апреля 2010

В вашем примере это потому, что вы не можете иметь список примитивного типа. Другими словами, List<int> невозможно.

Вы можете, однако, иметь List<Integer>, используя класс Integer, который охватывает примитив int. Преобразуйте ваш массив в List с помощью служебного метода Arrays.asList.

Integer[] spam = new Integer[] { 1, 2, 3 };
List<Integer> list = Arrays.asList(spam);

См. Этот код, запущенный в режиме реального времени на IdeOne.com .

133 голосов
/ 17 мая 2015

В Java 8 вы можете использовать потоки:

int[] spam = new int[] { 1, 2, 3 };
Arrays.stream(spam)
      .boxed()
      .collect(Collectors.toList());
124 голосов
/ 27 сентября 2014

Если говорить о способе конвертации, то это зависит от того, зачем вам нужен List. Если вам это нужно только для чтения данных. ОК, пошли:

Integer[] values = { 1, 3, 7 };
List<Integer> list = Arrays.asList(values);

Но тогда, если вы сделаете что-то вроде этого:

list.add(1);

вы получите java.lang.UnsupportedOperationException. Так что в некоторых случаях вам даже нужно это:

Integer[] values = { 1, 3, 7 };
List<Integer> list = new ArrayList<Integer>(Arrays.asList(values));

Первый подход на самом деле не конвертирует массив, а «представляет» его как List. Но массив находится под капотом со всеми его свойствами, такими как фиксированное количество элементов. Обратите внимание, что вам нужно указать тип при построении ArrayList.

118 голосов
/ 09 апреля 2010

Проблема в том, что varargs появился в Java5 и, к сожалению, Arrays.asList() был перегружен и версией vararg. Таким образом, Arrays.asList(spam) понимается компилятором Java5 как параметр vararg массивов int.

Эта проблема более подробно объясняется в Effective Java 2nd Ed., Глава 7, Item 42.

82 голосов
/ 23 декабря 2015

Кажется, немного поздно, но вот мои два цента. У нас не может быть List<int>, поскольку int является примитивным типом, поэтому мы можем иметь только List<Integer>.

Java 8 (массив int)

int[] ints = new int[] {1,2,3,4,5};
List<Integer> list11 =Arrays.stream(ints).boxed().collect(Collectors.toList()); 

Java 8 и ниже (целочисленный массив)

Integer[] integers = new Integer[] {1,2,3,4,5};
List<Integer> list21 =  Arrays.asList(integers); // returns a fixed-size list backed by the specified array.
List<Integer> list22 = new ArrayList<>(Arrays.asList(integers)); // good
List<Integer> list23 = Arrays.stream(integers).collect(Collectors.toList()); //Java 8 only

Нужен ArrayList, а не список?

В случае, если мы хотим конкретную реализацию List, например. ArrayList тогда мы можем использовать toCollection как:

ArrayList<Integer> list24 = Arrays.stream(integers)
                          .collect(Collectors.toCollection(ArrayList::new));

Почему list21 нельзя структурно изменить?

Когда мы используем Arrays.asList, размер возвращаемого списка фиксирован, потому что возвращаемый список не java.util.ArrayList, а закрытый статический класс, определенный внутри java.util.Arrays. Поэтому, если мы добавим или удалим элементы из возвращенного списка, будет выброшено UnsupportedOperationException. Поэтому мы должны пойти с list22, когда мы хотим изменить список. Если у нас есть Java8, то мы также можем перейти с list23.

Для ясности list21 можно изменить в том смысле, что мы можем вызвать list21.set(index,element), но этот список не может быть структурно изменен, т.е. не может добавлять или удалять элементы из списка. Вы также можете проверить этот вопрос .


Если мы хотим неизменный список, мы можем обернуть его как:

List<Integer> list 22 = Collections.unmodifiableList(Arrays.asList(integers));

Еще один момент, на который следует обратить внимание: метод Collections.unmodifiableList возвращает неизменяемое представление указанного списка. Неизменяемая коллекция представлений - это коллекция, которая не может быть изменена, а также является представлением резервной коллекции. Обратите внимание, что изменения в резервной коллекции все еще возможны, и если они происходят, они видны через неизменяемое представление.

У нас может быть действительно неизменный список в Java 10.

Java 10 (Действительно неизменный список) двумя способами:

  1. List.copyOf(Arrays.asList(integers))
  2. Arrays.stream(integers).collect(Collectors.toUnmodifiableList());

Также проверьте этот ответ моего для большего.

8 голосов
/ 31 августа 2014

Мне недавно пришлось преобразовать массив в список. Позже программа отфильтровала список, пытаясь удалить данные. Когда вы используете функцию Arrays.asList (array), вы создаете коллекцию фиксированного размера: вы не можете ни добавлять, ни удалять. Эта запись объясняет проблему лучше, чем я: Почему я получаю исключение UnsupportedOperationException при попытке удалить элемент из списка? .

В конце концов, мне пришлось сделать «ручное» преобразование:

    List<ListItem> items = new ArrayList<ListItem>();
    for (ListItem item: itemsArray) {
        items.add(item);
    }

Полагаю, я мог бы добавить преобразование из массива в список с помощью операции List.addAll (items).

7 голосов
/ 17 марта 2016

Еще короче:

List<Integer> list = Arrays.asList(1, 2, 3, 4);
5 голосов
/ 05 марта 2017

Использование массивов

Это самый простой способ преобразовать массив в List. Однако, если вы попытаетесь добавить новый элемент или удалить существующий элемент из списка, будет выброшено UnsupportedOperationException.

Integer[] existingArray = {1, 2, 3};
List<Integer> list1 = Arrays.asList(existingArray);
List<Integer> list2 = Arrays.asList(1, 2, 3);

// WARNING:
list2.add(1);     // Unsupported operation!
list2.remove(1);  // Unsupported operation!

Использование ArrayList или других реализаций списка

Вы можете использовать цикл for для добавления всех элементов массива в реализацию List, например, ArrayList

List<Integer> list = new ArrayList<>();
for (int i : new int[]{1, 2, 3}) {
  list.add(i);
}

Использование Stream API в Java 8

Вы можете превратить массив в поток, а затем собрать поток с помощью различных сборщиков: сборщик по умолчанию в Java 8 использует ArrayList за экраном, но вы также можете навязать предпочтительную реализацию.

List<Integer> list1, list2, list3;
list1 = Stream.of(1, 2, 3).collect(Collectors.toList());
list2 = Stream.of(1, 2, 3).collect(Collectors.toCollection(ArrayList::new));
list3 = Stream.of(1, 2, 3).collect(Collectors.toCollection(LinkedList::new));

Смотри также:

3 голосов
/ 12 августа 2016

Если вы ориентируетесь на Java 8 (или более позднюю версию), вы можете попробовать это:

int[] numbers = new int[] {1, 2, 3, 4};
List<Integer> integers = Arrays.stream(numbers)
                        .boxed().collect(Collectors.<Integer>toList());

Примечание:

Обратите внимание на Collectors.<Integer>toList(), этот универсальный метод помогает избежать ошибки "Несоответствие типов: невозможно преобразовать из List<Object> в List<Integer>".

3 голосов
/ 21 сентября 2015

Еще один обходной путь, если вы используете apache commons-lang:

int[] spam = new int[] { 1, 2, 3 };
Arrays.asList(ArrayUtils.toObject(spam));

Где ArrayUtils.toObject преобразует int[] в Integer[]

...