Створити ArrayList з масиву


3595

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

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

Я хотів би перетворити цей масив в об’єкт ArrayListкласу.

ArrayList<Element> arraylist = ???;

49
У Java9 -> Список <String> list = List.of ("Привіт", "Світ", "від", "Java");
MarekM

18
@MarekM Ця відповідь неправильна, оскільки це не повертає ArrayList. Плакат просив спеціально для цього.
Доріан Грей

4
Я думаю, що він не міняв, використовуючи список інтерфейсів, тому що це найкраща практика. Але якщо ви хочете ось це - новий ArrayList <> (List.of ("Привіт", "Світ", "від", "Java"));
MarekM

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

Відповіді:


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

361
Так. І в (найпоширенішому) випадку, коли ви просто хочете отримати список, new ArrayListдзвінок також є непотрібним.
Калум

143
@Luron - просто користуйсяList<ClassName> list = Arrays.asList(array)
басейн

247
@Calum та @Pool - як зазначено нижче у відповіді Алекса Міллера, використовуючи, Arrays.asList(array)не передаючи його в новий ArrayListоб’єкт, виправите розмір списку. Однією з найпоширеніших причин використання анкети ArrayListє можливість динамічно змінювати його розмір, і ваша пропозиція запобіжить цьому.
Code Jockey

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. Список, повернутий з списку, має фіксований розмір . Отже, якщо ви хочете мати змогу додавати або видаляти елементи зі списку, що повертається у своєму коді, вам потрібно буде обернути його в новий ArrayList. Інакше ви отримаєте UnsupportedOperationException.
  2. Список, повернутий з asList()якого, підтримується оригінальним масивом. Якщо ви модифікуєте оригінальний масив, список також буде змінено. Це може дивувати.

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

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

27
Переміщення в новий ArrayList () призведе до ітерації всіх елементів списку фіксованих розмірів і додавання до нового ArrayList, так само O (n).
Алекс Міллер

8
реалізація списку, поверненого asList (), не реалізує декілька методів List (наприклад, add (), remove (), clear () тощо), що пояснює UnsupportedOperationException. безумовно застереження ...
sethro

8
Коли питання задає "об'єкт класу ArrayList", я вважаю, що розумно вважати клас, на який він посилається java.util.ArrayList. Arrays.asList фактично повертає a, java.util.Arrays.ArrayListякий не є instanceofіншим класом. Отже, третє застереження полягає в тому, що якщо ви спробуєте використовувати його в контексті, що вимагає вище, це не вийде.
Дейв Л.

352

(стара нитка, але всього 2 центи, як жодна згадка про Гуаву чи інші мочки та деякі інші деталі)

Якщо можете, використовуйте Гуаву

Варто вказати шлях Гуави, який значно спрощує ці шенагігани:

Використання

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

Використовуйте 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 приїхала з новим оператором алмазів.

Але це не єдина причина (а 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але фактично безпосередньо посилається на пройдений масив і змушує його "записувати через" (модифікації відображаються в масиві).

Він забороняє модифікації за допомогою деяких Listметодів API шляхом простого розширення 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 + невірний. Ви instanciating списків String, і намагаєтеся витягти рядки з заданого масиву, замість того , щоб використовувати загальний тип параметра, T. Крім того, хороша відповідь та +1 за те, що є єдиним, включаючи ручний спосіб.
afsantos

Я перейменував свій розділ "Якщо ви не можете ... / для незмінного списку" в "Для немодифікуемого списку", оскільки його можна змінити в результаті пізніх змін оберненого масиву. Це все ще є O(1), але для незмінності вам потрібно зробити копію, наприклад, від Collections.unmodifiableList(new ArrayList<>(Arrays.asList(array))).
maaartinus

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

96

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 пропонує деякі зручні фабричні методи для Java Collections API. Ці незмінні статичні фабричні методи вбудовані в List, Setі Mapінтерфейси в Java 9 і пізніших версій.


List.of () не поверне примірник java.util.ArrayList, як вимагається в оригінальному запитанні. Тому лише другий варіант є правильною відповіддю.
tquadrat

84

Напевно, вам просто потрібен список, а не ArrayList. У такому випадку ви можете просто зробити:

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

8
Це буде підкріплене оригінальним вхідним масивом, саме тому ви (ймовірно) хочете обернути його в новий ArrayList.
Білл Ящірка

16
Будьте обережні з цим рішенням. Якщо ви подивитесь, Arrays НЕ повертає справжній java.util.ArrayList. Це повернення внутрішнього класу, який реалізує необхідні методи, але ви не можете змінити пам'ять у списку. Це просто обгортка навколо масиву.
Mikezx6r

1
Ви можете передати елемент Список <Element> до ArrayList <Element>
monksy

12
@ Mikezx6r: невелика корекція : це фіксований розмір. Ви можете змінити елементи списку ( setметод), ви не можете змінити розмір списку (не addабо removeелементів)!
користувач85421

1
Так, із застереженням, що це залежить від того, що ви хочете зробити зі списком. Варто зауважити, що якщо ОП просто хоче перейти через елементи, масив взагалі не повинен перетворюватися.
PaulMurrayCbr

69

Ще одне оновлення, майже закінчуючи 2014 рік, ви також можете зробити це з Java 8:

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

Кілька символів було б збережено, якби це могло бути лише a List

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

8
Напевно, найкраще не залежати від реалізації, але Collectors.toList()насправді повертає ArrayList.
bcsb1001

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

Я не думаю, що два варіанти є дійсними, але Arrays.stream трохи «кращий», оскільки ви можете створити його з фіксованим розміром, використовуючи метод перевантаження з аргументами 'start', 'end'. Дивіться також: stackoverflow.com/a/27888447/2619091
whyem

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

30
// Guava
import com.google.common.collect.ListsLists
...
List<String> list = Lists.newArrayList(aStringArray); 


21

як усі сказали, що це буде так

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

а загальний найновіший спосіб створення масиву - спостерігаєтьсяArrays

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, використовуючи цикл для кожного.

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()метод інтерфейсу колекції для копіювання вмісту з одного списку в інший.

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

Це менш ефективно, ніж прийнята 9-річна відповідь.
AjahnCharles

2
Один із ArrayListконструкторів s приймає ? extends Collection<T>аргумент, роблячи виклик addAllзайвим.
Tamoghna Chowdhury

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


Список <Element> elementList = Arrays.asList (масив) створює обгортку над початковим масивом, що робить оригінальний масив доступним як List. Отже, створюється об’єкт обгортки, нічого не копіюється з вихідного масиву. Тому такі дії, як додавання або видалення елементів, не дозволені.
Приянка

3
Зауважте, що ваша "незмінна колекція" насправді не змінюється - Listповернута сторінка Arrays.asListє лише обгорткою над початковим масивом і дозволяє отримати доступ та змінити окремі елементи через getта set. Вам, мабуть, слід уточнити, що ви маєте на увазі "не додавати та не видаляти елементи" замість "незмінного", що означає взагалі не змінюватись.
Tamoghna Chowdhury

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.