Питання Створіть ArrayList з масиву


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

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

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

ArrayList<Element> arraylist = ???;

2967
2017-10-01 14:38


походження


У Java9 -> List <String> list = List.of ("Hello", "World", "from", "Java"); - MarekM
@MarekM Ця відповідь неправильна, оскільки це не повертає ArrayList. Плакат на це спеціально запитував. - Tobias Weimer
Я думаю, що він не міг використовувати інтерфейс List, тому що це краща практика. Але якщо ви хочете, тут є - новий ArrayList <> (List.of ("Hello", "World", "from", "Java")); - MarekM
Сенс полягає не в тому, щоб використовувати інтерфейс, а в тому, що у вашому вирішенні повернений список не змінюється. Це може бути більшою проблемою і причиною, через яку він попросив ArrayList - Tobias Weimer


Відповіді:


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

3971
2017-10-01 14:39



Так. І в (найпоширенішому) випадку, коли ви просто хочете список, new ArrayList дзвінок також необов'язково. - Calum
@Luron - просто використовуйте List<ClassName> list = Arrays.asList(array) - Pool
@Calum і @Pool - як зазначено нижче в відповіді Алекса Міллера, використовуючи Arrays.asList(array) не передаючи його новому ArrayList об'єкт буде фіксувати розмір списку. Одна з найбільш поширених причин використання ArrayList це мати можливість динамічно змінювати свій розмір, і ваша пропозиція це дозволить запобігти цьому. - Code Jockey
Arrays.asList () - жахлива функція, і ви ніколи не повинні просто використовувати його повернення значення як є. Вона порушує шаблон списку, тому завжди використовуйте його у формі, вказаній тут, навіть якщо це здається зайвим. Гарна відповідь. - Adam
@ Адам Будь ласка, вивчіть javadoc для java.util.List. Договір про додавання дозволяє їм викинути UnsupportedOperationException. docs.oracle.com/javase/7/docs/api/java/util/...  Звичайно, з об'єктно-орієнтованої перспективи це не дуже приємно, що багато разів ви повинні знати конкретну реалізацію, щоб використовувати колекцію - це був вибір прагматичного дизайну, щоб зберегти структуру простою. - lbalazscs


Дано:

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() підтримується оригінальним масивом. Якщо ви зміните оригінальний масив, список також буде змінений. Це може бути дивним.

775
2017-10-01 15:39



Яка часова складність обох операцій? Я маю на увазі з використанням і без використання явного арралістського конструкції. - damned
Arrays.asList () створює лише ArrayList шляхом обертання існуючого масиву, так що це O (1). - Alex Miller
Обгортання в новому ArrayList () призведе до повторення всіх елементів списку фіксованих розмірів та додавання їх до нового ArrayList, тобто O (n). - Alex Miller
реалізація списку, поверненого asList (), не реалізує декілька методів List (наприклад, add (), remove (), clear (), і т. д.), що пояснює UnsupportedOperationException. безперечно застереження ... - sethro
Коли питання запитує "об'єкт класу ArrayList", я вважаю розумним припустити, що клас, до якого він посилається, є java.util.ArrayList. Масив.asList фактично повертає a java.util.Arrays.ArrayList який не є instanceof інший клас. Таким чином, третє застереження полягає в тому, що якщо ви спробуєте використовувати його в контексті, що вимагає вищенаведеного, це не спрацює. - Dave L.


(стара тема, але лише 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 ще не скрізь): синтаксис скорочень також дуже зручний, а ініціалізатори способів, як показано вище, дозволяють писати більш виразний код. Ви робите в одному гуавському дзвінку те, що займає 2 з поточними колекціями Java.


Якщо ти не можеш ...

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

Використовуйте JDK Arrays клас і його asList() Заводський метод, загорнутий a 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);
}

295
2017-11-16 17:16



+1 Але зауважте, що List повернувся Arrays.asList змінюється в тому, що ви все одно можете set елементи - це просто не змінювати розмір. Для незмінних списків без Гуави ви можете згадати Collections.unmodifiableList. - Paul Bellora
@haylem У вашому розділі Для навчальних цілей: Добрий Ол "вручну, твій arrayToList для Java 1.5+ невірно. Ви створюєте списки String, і намагається вилучити рядки з даного масиву, замість використання типового типового параметра T. Крім того, хороша відповідь, а +1 - бути єдиним, що включає ручний спосіб. - afsantos


Оскільки це питання досить старе, мені здивувало те, що ще ніхто не запропонував найпростішої форми:

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

Що стосується Java 5 Arrays.asList() приймає параметр varargs, і ви не повинні будувати масив явно.


203
2018-06-22 11:30



Зокрема, List<String> a = Arrays.asList("first","second","third") - 18446744073709551615


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

Переконайтеся в цьому myArray такий же тип, як T. Ви отримаєте помилку компілятора, якщо спробуєте створити List<Integer>з масиву int, наприклад.


172
2017-10-01 14:40





Інший спосіб (хоча суттєво еквівалентний new ArrayList(Arrays.asList(array)) Рішення:

Collections.addAll(arraylist, array);

77
2018-04-03 23:20





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

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

62
2017-10-01 14:45



Це буде підкріплено оригінальним вхідним масивом, тому ви (ймовірно) захочете загорнути його в новий ArrayList. - Bill the Lizard
Будьте обережні з цим рішенням. Якщо ви дивитеся, масиви НЕ повертають істинну java.util.ArrayList. Це повертає внутрішній клас, який реалізує необхідні методи, але ви не можете змінити memebers у списку. Це просто обгортка навколо масиву. - Mikezx6r
Ви можете передавати елемент List <Element> елемент ArrayList <Element> - monksy
@ Mikezx6r: мало корекція: це список з фіксованим розміром. Ви можете змінити елементи списку (set метод), ви не можете змінити розмір списку (не add або remove елементи)! - Carlos Heuberger
Так, з застереженням, що це залежить від того, що ви хочете зробити зі списком. Варто не сказати, що якщо OP просто хоче ітерації через елементи, масив не повинен бути перетворений взагалі. - PaulMurrayCbr


Java 9

В Java 9, ви можете використовувати List.of статичний заводський метод для створення a List буквально Щось на зразок наступного:

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

Це поверне а незмінна список містить три елементи. Якщо ви хочете a змінний список, передати цей список до ArrayList конструктор:

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

JEP 269: заводські методи зручності для колекцій

JEP 269 забезпечує деякі зручності фабричних методів для Колекції Java API Ці незмінні статичні заводські методи вбудовані в List, Set, і Map інтерфейси в Java 9 і вище.


59
2018-04-17 16:58





Ще одне оновлення, майже до кінця 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());

54
2017-11-25 20:48



Напевно, краще не бути залежністю від реалізації, але Collectors.toList() насправді повертає ArrayList. - bcsb1001
неправильне використання Stream.of (...); що створить потік одного елемента. Замість цього використовуйте Arrays.stream - Patrick Parker
Я не вважаю так, 2 варіанти є правильними, але Arrays.stream трохи "краще", оскільки ви можете створити його з фіксованим розміром, використовуючи метод перевантаження з "start", "end" args. Дивись також: stackoverflow.com/a/27888447/2619091 - whyem


Для перетворення масиву в ArrayList розробники часто роблять це:

List<String> list = Arrays.asList(arr);// this is wrong way..

Arrays.asList() повернеть ArrayList, який є a private static class inside Arrays, це не клас java.util.ArrayList. The java.util.Arrays.ArrayList клас має set(), get(), contains() методів, але не має ніяких методів додавання елементів, тому його розмір фіксується. Щоб створити справжній ArrayList, ви повинні зробити це:

ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(arr));

Конструктор ArrayList може прийняти a Тип колекції, який також є супер типом для java.util.Arrays.ArrayList


47
2018-06-25 07:20



Це не неправильний шлях, якщо вам просто потрібен а List, і не потрібно ArrayList, які ви насправді не в більшості випадків. Більшість часу, коли розробники створюють ArrayList це звично, більше, ніж не потрібно. - Christoffer Hammarström
Погодьтеся з @ ChristofferHammarström, обидва дійсні List<String> list = Arrays.asList(arr);використовується для створення List і ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(arr));використовується для створення ArrayList. Мабуть, @Nepster тільки копію вставив витяг з programcreek.com/2013/04/... - Nikhil Katre