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

865

Как преобразовать массив в список в 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);
  • 18
    Я думаю, что ваш пример не работает: Arrays.asList(new int[] { 1, 2, 3 }) ; определенно не компилируется в Java 1.4.2, потому что int[] не является Object[] .
  • 1
    О, ты можешь быть прав. У меня не было компилятора Java 1.4.2, чтобы протестировать мой пример перед публикацией. Теперь, после вашего комментария и ответа Джо, все становится намного понятнее.
Показать ещё 4 комментария
Теги:
arrays
list
containers
data-conversion

18 ответов

1273
Лучший ответ

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

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

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

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

  • 95
    Или еще проще: Arrays.asList (1, 2, 3);
  • 33
    Откуда он знает, что нельзя создавать List<Integer[]> ?
Показать ещё 12 комментариев
119

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

int[] spam = new int[] { 1, 2, 3 };
Arrays.stream(spam)
      .boxed()
      .collect(Collectors.toList());
111

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

Эта проблема объясняется более подробно в "Эффективной Java 2-й редакции", глава 7, пункт 42.

  • 3
    Я понимаю, что случилось, но не почему это не задокументировано. Я ищу альтернативное решение без повторной реализации колеса.
  • 0
    Есть ли работа вокруг?
Показать ещё 1 комментарий
110

Говоря об обращении, это зависит от того, зачем вам нужен 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 необходимо указать тип.

  • 0
    «неизменность» смутила меня на мгновение. Очевидно, вы можете изменить значения массива. Вы не можете изменить его размер, как бы то ни было.
70

Кажется, немного поздно, но вот мои два цента. У нас не может быть 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 исключение 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());

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

  • 0
    Комментарий в вашем примере кода для Arrays.asList говорящий // Cannot modify returned list , неверен. List является изменяемым и фактически записывает изменения обратно в массив. Смотрите документацию класса Arrays.asList . Возможно, вы думали о Collections.unmodifiableList .
  • 0
    @BasilBourque Я имел в виду, что я не могу изменить структуру списка путем добавления / удаления, но могу изменить элементы.
Показать ещё 1 комментарий
8

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

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

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

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

  • 11
    new ArrayList<ListItem>(Arrays.asList(itemsArray)) будет к тому же
  • 1
    @BradyZhu: Приведенный выше ответ не решает мою проблему с массивом фиксированного размера, но вы в основном говорите здесь RTFM, что всегда плохо. Пожалуйста, объясните, что не так с ответом или не комментируйте.
Показать ещё 2 комментария
7

Еще короче:

List<Integer> list = Arrays.asList(1, 2, 3, 4);
5

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

Это самый простой способ преобразования массива в 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

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

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

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

3

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

2
  • Использование Guava:

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

    Integer[] array = { 1, 2, 3};
    List<Integer> list = new ArrayList<>(6);
    CollectionUtils.addAll(list, array);
    
2

Однострочник:

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

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

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

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

2

вам нужно включить в массив

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

Массив в Java - это структура данных фиксированной длины, размер которой, когда она определена, не может быть изменен. Принимая во внимание, что ArrayList в Java является классом Collection переменной длины, размер которого изменяется по мере добавления в него нового элемента.

Массив быстрее, чем ArrayList, потому что ArrayList использует фиксированное количество массива. Однако, когда вы добавляете элемент в ArrayList, и он переполняется (превышает его фактический размер, определенный при запуске). Он создает новый массив и копирует каждый элемент из старого в новый. По этой причине программисты предпочитают Array, а не ArrayList. Но в реальных приложениях всегда необходимо преобразовать Array в ArrayList. Это можно сделать напрямую, используя встроенную функцию Java для преобразования String Array в ArrayList.

Синтаксис для преобразования String Array в ArrayList:

 List<String> a = new ArrayList<String>(Arrays.asList(StringObject));

Пример преобразования в ArrayList из Array:

import java.util.Arrays;
    import java.util.List;
    import java.util.ArrayList;

    public class ArrayToArrayList {

                public static void main(String[] args) {

                     String[] str = {"Solution","Factory"}; 

                     List<String> a = new ArrayList<String>(Arrays.asList(str));

                         System.out.println(a);

                 }
    }

Для получения дополнительной информации нажмите: https://www.solutionfactory.in/posts/How-to-Convert-String-Array-to-ArrayList-in-Java

0

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

public static <T> ArrayList<T> ArrayToArrayList(T[] array) {
    ArrayList<T> list = new ArrayList<T>();
    for(T elmt : array) list.add(elmt);
    return list;
}
  • 0
    Что если это не поможет? Тогда что ты сделал ?? ... JK :)
0

Итак, это зависит от того, какую версию 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/

-2

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню