Создать ArrayList из массива


3599

У меня есть массив, который инициализируется как:

Element[] array = {new Element(1), new Element(2), new Element(3)};

Я хотел бы преобразовать этот массив в объект ArrayListкласса.

ArrayList<Element> arraylist = ???;

50
В Java9 -> List <String> list = List.of («Hello», «World», «from», «Java»);
— MarekM

18
@MarekM Этот ответ неправильный, так как не возвращает ArrayList. Афиша просила специально для этого.
— Дориан Грей

4
Я думаю, что он не использовал интерфейс List, потому что это лучшая практика. Но если вы хотите здесь - new ArrayList <> (List.of («Hello», «World», «from», «Java»));
— MarekM

10
Дело не в использовании интерфейса, а в том, что в вашем решении возвращаемый список не подлежит изменению. Это может быть больше проблемой, и причиной, почему он попросил ArrayList
— Дориан Грей

Ответы:


4604
new ArrayList<>(Arrays.asList(array));

362
Ага. И в (наиболее распространенном) случае, когда вам нужен только список, new ArrayListвызов также не нужен.
— Калум

143
@Luron - просто используйтеList<ClassName> list = Arrays.asList(array)
— Pool

249
@Calum и @Pool - как отмечено ниже в ответе Алекса Миллера, использование Arrays.asList(array)без передачи его в новый ArrayListобъект будет фиксировать размер списка. Одной из наиболее распространенных причин использования ArrayListявляется возможность динамически изменять его размер, и ваше предложение предотвратит это.
— Код жокея

130
Arrays.asList () - ужасная функция, и вы никогда не должны просто использовать ее возвращаемое значение как есть. Он нарушает шаблон списка, поэтому всегда используйте его в указанной здесь форме, даже если он кажется избыточным. Хороший ответ.
— Адам

83
@ Adam Пожалуйста, изучите Javadoc для java.util.List. Контракт на добавление позволяет им генерировать исключение UnsupportedOperationException. docs.oracle.com/javase/7/docs/api/java/util/… По общему признанию, с объектно-ориентированной точки зрения не очень хорошо, что много раз вам приходится знать конкретную реализацию, чтобы использовать коллекцию - это был прагматичный выбор дизайна для того, чтобы сохранить рамки простыми.
— lbalazscs

918

Данный:

Element[] array = new Element[] { new Element(1), new Element(2), new Element(3) };

Самый простой ответ:

List<Element> list = Arrays.asList(array);

Это будет работать нормально. Но некоторые предостережения:

  1. Список, возвращаемый из asList, имеет фиксированный размер . Итак, если вы хотите иметь возможность добавлять или удалять элементы из возвращенного списка в вашем коде, вам нужно обернуть его в новый ArrayList. В противном случае вы получите UnsupportedOperationException.
  2. Список, возвращаемый из asList(), поддерживается исходным массивом. Если вы измените исходный массив, список также будет изменен. Это может быть удивительно.

6
Какова временная сложность обеих операций? Я имею в виду с и без использования явной конструкции arraylist.
— проклятый

35
Arrays.asList () просто создает ArrayList, оборачивая существующий массив, чтобы он был O (1).
— Алекс Миллер

27
Обтекание в новом ArrayList () приведет к тому, что все элементы списка фиксированного размера будут повторяться и добавляться в новый ArrayList, равно как и O (n).
— Алекс Миллер

8
реализация List, возвращаемая asList (), не реализует несколько методов List (таких как add (), remove (), clear () и т. д.), что объясняет исключение UnsupportedOperationException. определенно предостережение ...
— Sethro

8
Когда вопрос задает «объект класса ArrayList», я думаю, что разумно предположить, что класс, на который он ссылается, - это java.util.ArrayList. Arrays.asList фактически возвращает класс, java.util.Arrays.ArrayListкоторый не является instanceofдругим классом. Поэтому третье предостережение заключается в том, что если вы попытаетесь использовать его в контексте, требующем вышеуказанного, он не будет работать.
— Дейв Л.

352

(старая ветка, но всего 2 цента, так как никто не упоминает Guava или других библиотек и некоторые другие детали)

Если можете, используйте гуаву

Стоит указать путь гуавы, который значительно упрощает эти махинации:

Применение

Для неизменного списка

Используйте ImmutableListкласс и его методы of()и copyOf()методы фабрики (элементы не могут быть нулевыми) :

List<String> il = ImmutableList.of("string", "elements");  // from varargs
List<String> il = ImmutableList.copyOf(aStringArray);      // from array

Для изменяемого списка

Используйте Listsкласс и его newArrayList()фабричные методы:

List<String> l1 = Lists.newArrayList(anotherListOrCollection);    // from collection
List<String> l2 = Lists.newArrayList(aStringArray);               // from array
List<String> l3 = Lists.newArrayList("or", "string", "elements"); // from varargs

Также обратите внимание на аналогичные методы для других структур данных в других классах, например, в Sets.

Почему гуава?

Основная привлекательность может заключаться в уменьшении беспорядка из-за обобщений для безопасности типов, поскольку использование фабричных методов Гуавы позволяет выводить типы в большинстве случаев. Тем не менее, этот аргумент содержит меньше воды, так как Java 7 прибыл с новым оператором Diamond.

Но это не единственная причина (и Java 7 еще не везде): сокращенный синтаксис также очень удобен, а инициализаторы методов, как показано выше, позволяют писать более выразительный код. Вы делаете в одном вызове Guava то, что занимает 2 с текущими коллекциями Java.


Если ты не можешь ...

Для неизменного списка

Используйте Arraysкласс JDK и его asList()фабричный метод, заключенный в Collections.unmodifiableList():

List<String> l1 = Collections.unmodifiableList(Arrays.asList(anArrayOfElements));
List<String> l2 = Collections.unmodifiableList(Arrays.asList("element1", "element2"));

Обратите внимание, что возвращаемый тип для asList()является Listиспользованием конкретной ArrayListреализации, но это не так java.util.ArrayList . Это внутренний тип, который эмулирует, ArrayListно на самом деле напрямую ссылается на переданный массив и заставляет его «проходить через» (изменения отражаются в массиве).

Он запрещает модификацию некоторых методов ListAPI путем простого расширения AbstractList(поэтому добавление или удаление элементов не поддерживается), однако он допускает вызовы set()для переопределения элементов. Таким образом, этот список не является действительно неизменным, и вызов asList()должен быть заключен в Collections.unmodifiableList().

Смотрите следующий шаг, если вам нужен изменяемый список.

Для изменяемого списка

То же, что и выше, но обернуто фактическим java.util.ArrayList:

List<String> l1  = new ArrayList<String>(Arrays.asList(array));    // Java 1.5 to 1.6
List<String> l1b = new ArrayList<>(Arrays.asList(array));          // Java 1.7+
List<String> l2  = new ArrayList<String>(Arrays.asList("a", "b")); // Java 1.5 to 1.6
List<String> l2b = new ArrayList<>(Arrays.asList("a", "b"));       // Java 1.7+

Для образовательных целей: хороший старый ручной путь

// for Java 1.5+
static <T> List<T> arrayToList(final T[] array) {
  final List<T> l = new ArrayList<T>(array.length);

  for (final T s : array) {
    l.add(s);
  }
  return (l);
}

// for Java < 1.5 (no generics, no compile-time type-safety, boo!)
static List arrayToList(final Object[] array) {
  final List l = new ArrayList(array.length);

  for (int i = 0; i < array.length; i++) {
    l.add(array[i]);
  }
  return (l);
}

27
+1 Но обратите внимание, что Listвозвращаемое значение Arrays.asListявляется изменяемым, поскольку вы все еще можете setэлементы - оно просто не может быть изменено. Для неизменяемых списков без гуавы вы могли бы упомянуть Collections.unmodifiableList.
— Пол Беллора

1
@haylem В вашем разделе для образовательных целей: Хороший путь , ваш путьarrayToList для Java 1.5+ неверен. Вы создаете экземпляры списков Stringи пытаетесь получить строки из данного массива вместо использования общего типа параметра T. Кроме этого, хороший ответ и +1 за то, что он единственный, включая ручной способ.
— afsantos

Я бы переименовал ваш раздел «Если вы не можете ... / Для неизменного списка» на «Для неизменяемого списка», так как он может быть изменен последующими изменениями в упакованном массиве. Это все еще O(1), но для неизменности вы должны сделать копию, например, с помощью Collections.unmodifiableList(new ArrayList<>(Arrays.asList(array))).
— Маартин

232

Поскольку этот вопрос довольно старый, меня удивляет, что никто еще не предложил простейшую форму:

List<Element> arraylist = Arrays.asList(new Element(1), new Element(2), new Element(3));

Начиная с Java 5, Arrays.asList()принимает параметр varargs, и вам не нужно явно создавать массив.


7
В частности,List<String> a = Arrays.asList("first","second","third")
— 18446744073709551615

209
new ArrayList<T>(Arrays.asList(myArray));

Убедитесь, что myArrayэто тот же тип, что и T. Вы получите ошибку компилятора, если попытаетесь создать , например, List<Integer>из массива int.


103

Другой способ (хотя по сути эквивалентный new ArrayList(Arrays.asList(array))решению с точки зрения производительности:

Collections.addAll(arraylist, array);

97

Java 9

В Java 9 вы можете использовать List.ofстатический метод фабрики для создания Listлитерала. Что-то вроде следующего:

List<Element> elements = List.of(new Element(1), new Element(2), new Element(3));

Это вернет неизменный список, содержащий три элемента. Если вы хотите непостоянный список, передайте этот список ArrayListконструктору:

new ArrayList<>(List.of(// elements vararg))

JEP 269: методы фабрики удобства для коллекций

JEP 269 предоставляет некоторые удобные фабричные методы для API коллекций Java . Эти неизменные статические фабричные методы встроены в List, Setи Mapинтерфейсы в Java 9 и более поздних версий.


List.of () не будет возвращать экземпляр java.util.ArrayList, как было запрошено в исходном вопросе. Поэтому только второй вариант является правильным ответом.
— 19

84

Вам, вероятно, просто нужен список, а не ArrayList. В этом случае вы можете просто сделать:

List<Element> arraylist = Arrays.asList(array);

8
Это будет поддерживаться исходным входным массивом, поэтому вы (вероятно) хотите обернуть его в новый ArrayList.
— Билл Ящерица

16
Будьте осторожны с этим решением. Если вы посмотрите, Arrays НЕ возвращает истинный java.util.ArrayList. Он возвращает внутренний класс, который реализует требуемые методы, но вы не можете изменить члены в списке. Это просто оболочка вокруг массива.
— Mikezx6r

1
Вы можете
— разыграть

12
@ Mikezx6r: небольшое исправление : это список фиксированного размера. Вы можете изменить элементы списка ( setметод), вы не можете изменить размер списка (нет addили removeэлементы)!
— user85421

1
Да, с оговоркой, что это зависит от того, что вы хотите сделать со списком. Стоит отметить, что если OP просто хочет перебрать элементы, массив вообще не нужно конвертировать.
— PaulMurrayCbr

69

Еще одно обновление, почти заканчивающееся 2014 годом, вы можете сделать это и с Java 8:

ArrayList<Element> arrayList = Stream.of(myArray).collect(Collectors.toCollection(ArrayList::new));

Несколько символов будут сохранены, если это может быть просто List

List<Element> list = Stream.of(myArray).collect(Collectors.toList());

8
Вероятно, лучше не зависеть от реализации, но на Collectors.toList()самом деле возвращает ArrayList.
— bcsb1001

неправильное использование Stream.of (...); это создаст поток из одного элемента. Вместо этого используйте Arrays.stream
— Патрик Паркер

Я не думаю, что 2 варианта допустимы, но Arrays.stream немного «лучше», так как вы можете создать его с фиксированным размером, используя метод перегрузки с аргументами «start», «end». См. Также: stackoverflow.com/a/27888447/2619091
— почему

41

Если вы используете:

new ArrayList<T>(Arrays.asList(myArray));

Вы можете создать и заполнить два списка! Заполнение дважды большого списка - это именно то, что вы не хотите делать, потому что он будет создавать новый Object[]массив каждый раз, когда необходимо увеличить емкость.

К счастью, реализация JDK быстрая и Arrays.asList(a[])очень хорошо сделана. Он создает вид ArrayList с именем Arrays.ArrayList, где данные Object [] указывают непосредственно на массив.

// in Arrays
@SafeVarargs
public static <T> List<T> asList(T... a) {
    return new ArrayList<>(a);
}
//still in Arrays, creating a private unseen class
private static class ArrayList<E>

    private final E[] a;    
    ArrayList(E[] array) {
        a = array; // you point to the previous array
    }
    ....
}

Опасная сторона в том, что если вы измените исходный массив, вы измените список! Вы уверены, что хотите этого? Может да может нет.

Если нет, то самый понятный способ сделать это:

ArrayList<Element> list = new ArrayList<Element>(myArray.length); // you know the initial capacity
for (Element element : myArray) {
    list.add(element);
}

Или, как сказал @glglgl, вы можете создать еще один независимый ArrayList с помощью:

new ArrayList<T>(Arrays.asList(myArray));

Я люблю использовать Collections, Arrays, или Guava. Но если он не подходит или вы этого не чувствуете, просто напишите еще одну не элегантную строку.


1
Я не вижу принципиальной разницы между вашей петлей в конце ответа и той new ArrayList<T>(Arrays.asList(myArray));частью, которую вы не хотите использовать. Оба делают одно и то же и имеют одинаковую сложность.
— glglgl

Коллекции создают указатель на начало массива. Мой цикл создает много указателей: по одному для каждого члена массива. Таким образом, если исходный массив изменяется, мои указатели все еще направлены на прежние значения.
— Николас Зозол

1
new ArrayList<T>(Arrays.asList(myArray));делает то же самое, он копирует asListАнь ArrayList...
— glglgl

37

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

List<String> list = List.of("Hello", "World", "from", "Java");
List<Integer> list = List.of(1, 2, 3, 4, 5);

Обратите внимание, что это не ArrayList, как это было явно задано.
— Дориан Грэй,

33

В соответствии с вопросом ответ с использованием Java 1.7:

ArrayList<Element> arraylist = new ArrayList<Element>(Arrays.<Element>asList(array));

Однако лучше всегда использовать интерфейс:

List<Element> arraylist = Arrays.<Element>asList(array);


22

Вы можете конвертировать, используя разные методы

  1. List<Element> list = Arrays.asList(array);

  2. List<Element> list = new ArrayList();
    Collections.addAll(list, array);

  3. Arraylist list = new Arraylist();
    list.addAll(Arrays.asList(array));

Для получения более подробной информации вы можете обратиться к http://javarevisited.blogspot.in/2011/06/converting-array-to-arraylist-in-java.html


21

как все сказали, так и будет

 new ArrayList<>(Arrays.asList("1","2","3","4"));

и самый распространенный способ создания массива - observableArrays

ObservableList: список, который позволяет слушателям отслеживать изменения, когда они происходят.

для Java SE вы можете попробовать

FXCollections.observableArrayList(new Element(1), new Element(2), new Element(3));

то есть согласно Oracle Docs

observableArrayList () Создает новый пустой список наблюдаемых, который поддерживается массивом. observableArrayList (E ... items) Создает новый список наблюдаемых массивов с добавленными в него элементами.

Обновите Java 9

также в Java 9 это немного просто:

List<String> list = List.of("element 1", "element 2", "element 3");

20

Начиная с Java 8 существует более простой способ преобразования:

public static <T> List<T> fromArray(T[] array) {
    return Arrays.stream(array).collect(toList());
}

18

Вы также можете сделать это с потоком в Java 8.

 List<Element> elements = Arrays.stream(array).collect(Collectors.toList()); 

3
По состоянию на Java 8 , Collectors.toList()вернет ArrayList. Однако это может отличаться в будущих версиях java. Если вы хотите определенный тип коллекции, используйте Collectors.toCollection()вместо нее, где вы можете указать, какой именно тип коллекции вы хотите создать.
— Раджа Анбажаган

14
  1. Если мы увидим определение Arrays.asList()метода, вы получите что-то вроде этого:

     public static <T> List<T> asList(T... a) //varargs are of T type. 

    Итак, вы можете инициализировать arraylistтак:

     List<Element> arraylist = Arrays.asList(new Element(1), new Element(2), new Element(3));

    Примечание : каждый new Element(int args)будет рассматриваться как отдельный объект и может быть передан как var-args.

  2. Там может быть другой ответ на этот вопрос тоже.
    Если вы видите объявление для java.util.Collections.addAll()метода, вы получите что-то вроде этого:

    public static <T> boolean addAll(Collection<? super T> c, T... a);

    Таким образом, этот код также полезен для этого

    Collections.addAll(arraylist, array);

10

Другой простой способ - добавить все элементы из массива в новый ArrayList, используя цикл for-each.

ArrayList<Element> list = new ArrayList<>();

for(Element e : array)
    list.add(e);

10

Если массив имеет примитивный тип, данные ответы не будут работать. Но начиная с Java 8 вы можете использовать:

int[] array = new int[5];
Arrays.stream(array).boxed().collect(Collectors.toList());

Это решение, похоже, не работает с charмассивом.
— PixelMaster

8

Вы можете сделать это в Java 8 следующим образом

ArrayList<Element> list = (ArrayList<Element>)Arrays.stream(array).collect(Collectors.toList());

1
Проголосовал, потому что этот состав выглядит очень опасно. ничто не указывает, что тип возвращаемого списка на самом деле является ArrayList, как утверждает javadoc: «Нет никаких гарантий относительно типа, изменчивости, сериализуемости или безопасности потока возвращаемого списка»
— Дориан Грей,

1
Если вы хотите явно создать ArrayList, попробуйте это:ArrayList<String> list = Arrays.stream(array).collect(Collectors.toCollection(ArrayList::new));
— Дориан Грей,

8

Мы можем легко преобразовать массив в ArrayList. Мы используем addAll()метод интерфейса Collection для копирования содержимого из одного списка в другой.

 Arraylist arr = new Arraylist();
 arr.addAll(Arrays.asList(asset));

Это менее эффективно, чем принятый 9-летний ответ.
— AjahnCharles

2
Один из ArrayListконструкторов принимает ? extends Collection<T>аргумент, делая вызов addAllизбыточным.
— Тамогна Чоудхури

7

Хотя на этот вопрос есть много прекрасно написанных ответов, я добавлю свои комментарии.

Скажи у тебя есть Element[] array = { new Element(1), new Element(2), new Element(3) };

Новый ArrayList может быть создан следующими способами

ArrayList<Element> arraylist_1 = new ArrayList<>(Arrays.asList(array));
ArrayList<Element> arraylist_2 = new ArrayList<>(
    Arrays.asList(new Element[] { new Element(1), new Element(2), new Element(3) }));

// Add through a collection
ArrayList<Element> arraylist_3 = new ArrayList<>();
Collections.addAll(arraylist_3, array);

И они очень хорошо поддерживают все операции ArrayList

arraylist_1.add(new Element(4)); // or remove(): Success
arraylist_2.add(new Element(4)); // or remove(): Success
arraylist_3.add(new Element(4)); // or remove(): Success

Но следующие операции возвращают только представление списка ArrayList, а не фактический ArrayList.

// Returns a List view of array and not actual ArrayList
List<Element> listView_1 = (List<Element>) Arrays.asList(array);
List<Element> listView_2 = Arrays.asList(array);
List<Element> listView_3 = Arrays.asList(new Element(1), new Element(2), new Element(3));

Поэтому они будут выдавать ошибку при попытке выполнить некоторые операции ArrayList

listView_1.add(new Element(4)); // Error
listView_2.add(new Element(4)); // Error
listView_3.add(new Element(4)); // Error

Подробнее о представлении списка ссылки на массив .


7

Самый простой способ сделать это - добавить следующий код. Пробовал и проверял.

String[] Array1={"one","two","three"};
ArrayList<String> s1= new ArrayList<String>(Arrays.asList(Array1));

7

Другое решение Java8 (возможно, я пропустил ответ среди большого набора. Если так, мои извинения). Это создает ArrayList (в отличие от списка), то есть можно удалить элементы

package package org.something.util;

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

public class Junk {

    static <T> ArrayList<T>  arrToArrayList(T[] arr){
        return Arrays.asList(arr)
            .stream()
            .collect(Collectors.toCollection(ArrayList::new));
    }

    public static void main(String[] args) {
        String[] sArr = new String[]{"Hello", "cruel", "world"};
        List<String> ret = arrToArrayList(sArr);
        // Verify one can remove an item and print list to verify so
        ret.remove(1);
        ret.stream()
            .forEach(System.out::println);
    }
}

Вывод ...
Привет,
мир


7

Используйте следующий код для преобразования массива элементов в ArrayList.

Element[] array = {new Element(1), new Element(2), new Element(3)};

ArrayList<Element>elementArray=new ArrayList();
for(int i=0;i<array.length;i++) {
    elementArray.add(array[i]);
}

5

Уже каждый предоставил достаточно хороший ответ для вашей проблемы. Теперь из всех предложений, вам нужно решить, что будет соответствовать вашим требованиям. Есть два типа коллекций, которые вам нужно знать. Один - это немодифицированная коллекция, а другая - коллекция, которая позволит вам позже изменить объект.

Итак, здесь я приведу краткий пример для двух вариантов использования.

  • Создание неизменной коллекции :: Если вы не хотите изменять объект коллекции после создания

    List<Element> elementList = Arrays.asList(array)

  • Создание изменяемой коллекции :: Когда вы можете захотеть изменить созданный объект коллекции после создания.

    List<Element> elementList = new ArrayList<Element>(Arrays.asList(array));


List <Element> elementList = Arrays.asList (array) создает обертку над исходным массивом, которая делает исходный массив доступным как List. Следовательно, создается объект-обертка, из исходного массива ничего не копируется. Поэтому такие операции, как добавление или удаление элементов, не допускаются.
— Приянка

3
Обратите внимание, что ваша «неизменяемая коллекция» на самом деле не является неизменной - Listвозвращаемое значение Arrays.asListявляется просто оберткой над исходным массивом и позволяет отдельным элементам получать доступ и изменять их с помощью getи set. Вы, вероятно, должны уточнить, что вы имеете в виду «не добавлять и не удалять элементы» вместо «неизменяемый», что означает вообще не изменять.
— Тамогна Чаудхури

5

Данный объектный массив:

Element[] array = {new Element(1), new Element(2), new Element(3) , new Element(2)};

Преобразовать массив в список:

    List<Element> list = Arrays.stream(array).collect(Collectors.toList());

Конвертировать массив в ArrayList

    ArrayList<Element> arrayList = Arrays.stream(array)
                                       .collect(Collectors.toCollection(ArrayList::new));

Конвертировать массив в LinkedList

    LinkedList<Element> linkedList = Arrays.stream(array)
                     .collect(Collectors.toCollection(LinkedList::new));

Список печати:

    list.forEach(element -> {
        System.out.println(element.i);
    });

ВЫВОД

1

2

3


4

Класс Arrays в Java 8 предоставляет метод stream () с перегруженными версиями, принимающими как примитивные, так и объектные массивы.

/**** Converting a Primitive 'int' Array to List ****/

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

List<Integer> integerList1 = Arrays.stream(intArray).boxed().collect(Collectors.toList());

/**** 'IntStream.of' or 'Arrays.stream' Gives The Same Output ****/

List<Integer> integerList2 = IntStream.of(intArray).boxed().collect(Collectors.toList());

/**** Converting an 'Integer' Array to List ****/

Integer integerArray[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

List<Integer> integerList3 = Arrays.stream(integerArray).collect(Collectors.toList());

3

Ниже код кажется хорошим способом сделать это.

new ArrayList<T>(Arrays.asList(myArray));
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.