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

1028

Как мне преобразовать массив в список в 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);
Александр
источник
20
Я думаю , что ваш пример сломан: Arrays.asList(new int[] { 1, 2, 3 }); определенно не компилировать Java 1.4.2, так как int[]это неObject[] .
Йоахим Зауэр
1
О, вы можете быть правы. У меня не было компилятора Java 1.4.2, чтобы протестировать мой пример перед публикацией. Теперь, после вашего комментария и ответа Джо, все становится намного понятнее.
Александру
1
Я думал, что Autoboxing покрыл бы преобразование из примитива в класс-оболочку Integer. Вы можете сначала выполнить приведение, а затем приведенный выше код Arrays.asListдолжен работать.
Horse Voice
2
Stream.boxed () Java 8 позаботится об автобоксе и может быть использован для этого. Смотрите мой ответ ниже .
Ибрагим Краткий обзор
Java 8 Решение: stackoverflow.com/questions/2607289/...
akhil_mittal

Ответы:

1431

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

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

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

Смотрите этот код в прямом эфире на IdeOne.com .

Джо Дейли
источник
112
Или еще проще: Arrays.asList (1, 2, 3);
Конг
45
Откуда оно знает не создавать List<Integer[]>?
Томас Але
25
Сбои в Java 5+.
Джечлин
6
@ThomasAhle Он не создает List <Integer []>, он создает объект List <Integer>. И если вы хотите быть в безопасности, напишите: Arrays. <Integer> asList (spam);
user1712376
6
@ThomasAhle Это хороший вопрос. Наверное, это просто правило в компиляторе Java. Например, следующий код возвращает список <Integer []> Integer[] integerArray1 = { 1 }; Integer[] integerArray2 = { 2 }; List<Integer[]> integerArrays = Arrays.asList(integerArray1, integerArray2);
Simon
167

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

int[] spam = new int[] { 1, 2, 3 };
Arrays.stream(spam)
      .boxed()
      .collect(Collectors.toList());
Ибрагим Ариф
источник
Это хорошо, но это не сработает boolean[]. Я думаю, это потому, что это так же легко сделать Boolean[]. Это, вероятно, лучшее решение. Во всяком случае, это интересная причуда.
ГленПетерсон
138

Если говорить о конверсии, то это зависит от того, зачем вам нужен 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));

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

Роман Никитченко
источник
1
«неизменность» смутила меня на мгновение. Очевидно, вы можете изменить значения массива. Вы не можете изменить его размер, однако.
Тим
125

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

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

Петер Тёрёк
источник
4
Я понимаю, что случилось, но не почему это не задокументировано. Я ищу альтернативное решение без повторной реализации колеса.
Александру
2
@UsmanIsmail Начиная с Java 8, мы можем использовать потоки для этого преобразования. Смотрите мой ответ ниже .
Ибрагим Краткий обзор
109

Кажется, немного поздно, но вот мои два цента. Мы не можем иметь 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 9 и 10.

Действительно неизменный список

Java 9:

String[] objects = {"Apple", "Ball", "Cat"};
List<String> objectList = List.of(objects);

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

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

Также проверьте мой ответ для получения дополнительной информации.

akhil_mittal
источник
@BasilBourque Я имел в виду, не может изменить структуру списка путем добавления / удаления, но может изменить элементы.
akhil_mittal
На самом деле, я попробовал некоторый код и подтвердил, что вызывать List::add& List::removeне удается с помощью списка, возвращенного Arrays.asList. JavaDoc для этого метода плохо написан и неясен по этому вопросу. В третьем чтении я полагаю, что фраза «фиксированного размера» означала, что нельзя добавлять или удалять элементы.
Базилик Бурк
12

Еще короче

List<Integer> list = Arrays.asList(1, 2, 3, 4);
Виталий Соколов
источник
11

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

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

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

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

Стив Гельман
источник
11
new ArrayList<ListItem>(Arrays.asList(itemsArray))будет к тому же
Marco13
1
@BradyZhu: Приведенный выше ответ не решает мою проблему с массивом фиксированного размера, но вы в основном говорите здесь RTFM, что всегда плохо. Пожалуйста, объясните, что не так с ответом или не комментируйте.
Стив Гельман
2
Инструменты проверки могут показывать предупреждение здесь, и вы назвали причину. Нет необходимости копировать элементы вручную, используйте Collections.addAll(items, itemsArray)вместо этого.
Дарек Кей
Просто нажмите это исключение. Боюсь, ответ Marco13 должен быть правильным. Возможно, мне понадобится пройти целый год, чтобы исправить все исключения asList.
7

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

Это самый простой способ конвертировать массив в 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));

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

Минконг Хуан
источник
6

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

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

Где ArrayUtils.toObject конвертируется int[]вInteger[]

Аластер
источник
5

Вы должны бросить в массив

Arrays.asList((Object[]) array)
Джанкарло Фрисон
источник
3
java: несовместимые типы: int [] нельзя преобразовать в java.lang.Object []
dVaffection
@dVaffection Затем приведите к int []. Важной частью является приведение к массиву.
Небрил
5

Один лайнер:

List<Integer> list = Arrays.asList(new Integer[] {1, 2, 3, 4});
Бхушан
источник
5

В Java 9 у вас есть еще более элегантное решение использования неизменяемых списков с помощью нового метода фабрики удобства List.of:

List<String> immutableList = List.of("one","two","three");

(бесстыдно скопировано отсюда )

Пьерлуиджи Вернетто
источник
К вашему сведению, чтобы узнать некоторые технические детали, стоящие за этим, см. JEP 269: Методы удобной фабрики для коллекций и доклад Стюарта Маркса , основного автора.
Василий Бурк
5

Если вы ориентируетесь на 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>».

nybon
источник
4
  1. Использование гуавы:

    Integer[] array = { 1, 2, 3};
    List<Integer> list = Lists.newArrayList(sourceArray);
  2. Использование коллекций Apache Commons:

    Integer[] array = { 1, 2, 3};
    List<Integer> list = new ArrayList<>(6);
    CollectionUtils.addAll(list, array);
Данаил Цветанов
источник
3

Если это помогает: у меня возникла та же проблема, и я просто написал универсальную функцию, которая принимает массив и возвращает ArrayList того же типа с тем же содержимым:

public static <T> ArrayList<T> ArrayToArrayList(T[] array) {
    ArrayList<T> list = new ArrayList<T>();
    for(T elmt : array) list.add(elmt);
    return list;
}
Kleines Filmröllchen
источник
Что если это не поможет? Тогда что ты сделал ?? ... jk :)
Sᴀᴍ Onᴇᴌᴀ
2

Данный массив:

    int[] givenArray = {2,2,3,3,4,5};

Преобразование целочисленного массива в список целых

Один из способов: boxed () -> возвращает IntStream

    List<Integer> givenIntArray1 = Arrays.stream(givenArray)
                                  .boxed()
                                  .collect(Collectors.toList());

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

ПРИМЕЧАНИЕ. Используя mapToObj, вы можете преобразовать каждый элемент int в поток строк, символьный поток и т. Д., Указав регистр i в (char) i

    List<Integer> givenIntArray2 = Arrays.stream(givenArray)
                                         .mapToObj(i->i)
                                         .collect(Collectors.toList());

Пример преобразования одного массива в другой тип:

List<Character> givenIntArray2 = Arrays.stream(givenArray)
                                             .mapToObj(i->(char)i)
                                             .collect(Collectors.toList());
Арпан Сайни
источник
1

Так что это зависит от того, какую версию Java вы пытаетесь

Java 7

 Arrays.asList(1, 2, 3);

ИЛИ

       final String arr[] = new String[] { "G", "E", "E", "K" };
       final List<String> initialList = new ArrayList<String>() {{
           add("C");
           add("O");
           add("D");
           add("I");
           add("N");
       }};

       // Elements of the array are appended at the end
       Collections.addAll(initialList, arr);

ИЛИ

Integer[] arr = new Integer[] { 1, 2, 3 };
Arrays.asList(arr);

В Java 8

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

Ссылка - http://www.codingeek.com/java/how-to-convert-array-to-list-in-java/

Хитеш Гарг
источник
1

Можете ли вы улучшить этот ответ, пожалуйста, так как это то, что я использую, но я не на 100% ясно. Работает нормально, но IntelliJ добавил новую WeatherStation [0]. Почему 0?

    public WeatherStation[] removeElementAtIndex(WeatherStation[] array, int index)
    {
        List<WeatherStation> list = new ArrayList<WeatherStation>(Arrays.asList(array));
        list.remove(index);
        return list.toArray(new WeatherStation[0]);
    }

DevilCode
источник
Почему мы должны улучшить ваш вопрос? Либо вы знаете ответ, либо нет. Конечно, вы должны дать ответ, который действительно помогает другим, а не тот, который смущает больше, чем помогает.
HimBromBeere
-2

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

  Integer [] arr={1,2};
  Arrays.asList(arr);
Юсеф
источник