Создать 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);
}
haylem
источник
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());
whyem
источник
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);
MarekM
источник
Обратите внимание, что это не ArrayList, как это было явно задано.
Дориан Грэй,
33

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

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

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

List<Element> arraylist = Arrays.<Element>asList(array);
nekperu15739
источник
30
// Guava
import com.google.common.collect.ListsLists
...
List<String> list = Lists.newArrayList(aStringArray); 
Богдана
источник
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

oxy_js
источник
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");
Abojemyeg
источник
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()); 
Vaseph
источник
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);
spencer.sm
источник
10

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

int[] array = new int[5];
Arrays.stream(array).boxed().collect(Collectors.toList());
A1M
источник
Это решение, похоже, не работает с charмассивом.
PixelMaster
8

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

ArrayList<Element> list = (ArrayList<Element>)Arrays.stream(array).collect(Collectors.toList());
Adit A. Pillai
источник
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));
rashedcs
источник
Это менее эффективно, чем принятый 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));
Hemin
источник
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));
Singh123
источник