Преобразование массива в список в 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 позаботится об автобоксе и может быть использован для этого. Смотрите мой ответ ниже .
Ибрагим Краткий обзор

Ответы:


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());

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


@BasilBourque Я имел в виду, не может изменить структуру списка путем добавления / удаления, но может изменить элементы.
akhil_mittal

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


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

В 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>».


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;
}

Что если это не поможет? Тогда что ты сделал ?? ... 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]);
    }


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

-2

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

  Integer [] arr={1,2};
  Arrays.asList(arr);
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.