Перетворення масиву в список на Java


1027

Як перетворити масив у список на 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);

20
Я думаю, що ваш приклад зламаний Arrays.asList(new int[] { 1, 2, 3 }):; безумовно не компілювати Java 1.4.2, так як int[]це НЕObject[] .
Йоахім Зауер

1
О, ти можеш мати рацію. У мене не було компілятора Java 1.4.2, щоб перевірити свій приклад перед публікацією. Тепер, після вашого коментаря та відповіді Джо, все має набагато більше сенсу.
Олександру

1
Я думав, що автобоксинг охопив би перетворення з примітивного класу в обгортковий Integer Спочатку ви можете скласти акторський склад, а потім Arrays.asListповинен працювати спрацьований вище код .
Кінський голос

2
Java 8's Stream.boxed () піклується про автобокс і може бути використаний для цього. Дивіться мою відповідь нижче .
Ібрагім Короткий

Відповіді:


1430

У вашому прикладі, це тому, що ви не можете мати Список примітивного типу. Іншими словами, List<int>це неможливо.

Тим не менш, ти можеш List<Integer>використовувати Integerклас, який обгортає intпримітив. Перетворіть свій масив в a Listза допомогою Arrays.asListутиліти.

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

Дивіться цей код, який виконується на веб-сайті IdeOne.com .


112
Або навіть простіше: Arrays.asList (1, 2, 3);
Конг

45
Звідки це знати, що не створювати List<Integer[]>?
Thomas Ahle

25
Помилки в Java 5+.
djechlin

6
@ThomasAhle Це не створює список <Integer []>, він створює об'єкт List <Integer>. І якщо ви хочете бути захищеними від типу, ви пишете: Arrays. <Integer> asList (спам);
користувач1712376

6
@ThomasAhle Це гарне запитання. Здогадка, це лише правило у компіляторі Java. Для прикладу наступний код повертає список <Integer []> Integer[] integerArray1 = { 1 }; Integer[] integerArray2 = { 2 }; List<Integer[]> integerArrays = Arrays.asList(integerArray1, integerArray2);
Simon

167

У Java 8 можна використовувати потоки:

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

Це добре, але це не спрацює boolean[]. Я думаю, це тому, що зробити так само просто Boolean[]. Це, мабуть, краще рішення. У всякому разі, це цікава примха.
GlenPeterson

138

Якщо говорити про спосіб конверсії, то це залежить від того, для чого вам потрібен ваш 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));

Перший підхід насправді не перетворює масив, а "представляє" його як a List. Але масив знаходиться під кришкою з усіма його властивостями, як фіксованою кількістю елементів. Зверніть увагу, вам потрібно вказати тип при будівництві ArrayList.


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

125

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

Ця проблема пояснюється більш докладно в Ефективній Java 2nd Ed., Глава 7, пункт 42.


4
Я розумію, що сталося, але не чому це не документально підтверджено. Я шукаю альтернативне рішення без повторного доповнення колеса.
Олександру

2
@UsmanIsmail Що стосується Java 8, ми можемо використовувати потоки для цього перетворення. Дивіться мою відповідь нижче .
Ібрагім Короткий

109

Здається, трохи пізно, але ось два мої центи. Ми не можемо мати, 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буде видано запит . Тож нам слід йти, list22коли ми хочемо змінити список. Якщо у нас є Java8, ми можемо також піти з цим list23.

Щоб бути зрозумілим, list21можна змінити сенс, який ми можемо викликати, list21.set(index,element)але цей список може бути не структурно модифікований, тобто не може додавати або видаляти елементи зі списку. Ви також можете перевірити це питання .


Якщо ми хочемо незмінного списку, то ми можемо перетворити його як:

List<Integer> list 22 = Collections.unmodifiableList(Arrays.asList(integers));

Ще один момент, який слід зазначити, полягає в тому, що метод Collections.unmodifiableListповертає немодифікований вигляд зазначеного списку. Колекція немодифікованих представлень - це колекція, яка не може змінюватися, а також є переглядом колекції, що підтримується. Зауважте, що зміни в резервній колекції все ще можливі, і якщо вони відбудуться, їх можна побачити через немодифікований вигляд.

Ми можемо мати справді незмінний список на Java 9 і 10.

Справді незмінний список

Java 9:

String[] objects = {"Apple", "Ball", "Cat"};
List<String> objectList = List.of(objects);

Java 10 (список справді незмінних) двома способами:

  1. List.copyOf(Arrays.asList(integers))
  2. Arrays.stream(integers).collect(Collectors.toUnmodifiableList());

Також перевірте цю відповідь моєї для отримання додаткової інформації.


@BasilBourque Я мав на увазі не може змінювати структуру списку шляхом додавання / видалення, але може змінювати елементи.
akhil_mittal

Дійсно, я спробував якийсь код і підтвердив, що дзвонити List::addі List::removeне вдається зі списком, повернутим Arrays.asList. JavaDoc для цього методу погано написаний і незрозумілий з цього приводу. У моєму третьому читанні, я вважаю, що словосполучення "фіксованого розміру" малося сказати, що не можна додавати або видаляти елементи.
Василь Бурк


11

Нещодавно мені довелося перетворити масив у Список. Пізніше програма відфільтрувала список, намагаючись видалити дані. Використовуючи функцію 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))до того ж
Marco13

1
@BradyZhu: Наведена відповідь вище не вирішує мою проблему з масивом фіксованого розміру, але ви в основному говорите тут RTFM, що завжди погана форма. Будь ласка, поясніть, що не так у відповіді або не коментуйте.
Стів Гелман

2
Тут інструменти перевірки можуть містити попередження, і ви назвали причину. Немає необхідності копіювати елементи вручну, використовуйте Collections.addAll(items, itemsArray)замість цього.
Дарек Кей

Просто натисніть на цей виняток. Боюся, відповідь Марко13 повинна бути правильною. Можливо, мені потрібно буде пройти цілий рік, щоб виправити всі винятки "asList".

7

Використання масивів

Це найпростіший спосіб перетворення масиву в 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));

Дивись також:


6

Інше рішення, якщо ви використовуєте apache commons-lang:

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

Де ArrayUtils.toObject перетворюється int[]вInteger[]


5

ви повинні подати в масив

Arrays.asList((Object[]) array)

3
java: несумісні типи: int [] не можна перетворити на java.lang.Object []
dVaffection

@dVaffection Потім передано до int []. Важлива частина - це передавання масиву.
Небріл


5

У Java 9 у вас є ще більш елегантне рішення використання незмінних списків за допомогою нового фабричного методу зручності List.of:

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

(безсоромно скопіювали звідси )


FYI, щоб дізнатися деякі технічні деталі, що стоять за цим, див. JEP 269: Фабричні методи колекцій для зручності та бесіда Стюарта Маркса , головного автора.
Василь Бурк

5

Якщо ви орієнтуєтесь на 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>".


4
  1. Використання Guava:

    Integer[] array = { 1, 2, 3};
    List<Integer> list = Lists.newArrayList(sourceArray);
  2. Використання колекцій Apache Commons:

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

3

Якщо це допомагає: У мене була та сама проблема, і я просто написав загальну функцію, яка приймає масив і повертає ArrayList того ж типу з тим самим вмістом:

public static <T> ArrayList<T> ArrayToArrayList(T[] array) {
    ArrayList<T> list = new ArrayList<T>();
    for(T elmt : array) list.add(elmt);
    return list;
}

Що робити, якщо це не допомагає? Тоді що ти зробив ?? ... jk :)
Sᴀᴍ Onᴇᴌᴀ

2

Дано масив:

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

Перетворення цілого масиву в цілий список

Один із способів: boxed () -> повертає IntStream

    List<Integer> givenIntArray1 = Arrays.stream(givenArray)
                                  .boxed()
                                  .collect(Collectors.toList());

Другий спосіб: картографуйте кожен елемент потоку до Integer, а потім збирайте

ПРИМІТКА: Використовуючи mapToObj, ви можете перекрити кожен елемент int у потоковий рядок, потік char тощо, використовуючи обкладинку i to (char) i

    List<Integer> givenIntArray2 = Arrays.stream(givenArray)
                                         .mapToObj(i->i)
                                         .collect(Collectors.toList());

Перетворення одного типу масиву в приклад іншого типу:

List<Character> givenIntArray2 = Arrays.stream(givenArray)
                                             .mapToObj(i->(char)i)
                                             .collect(Collectors.toList());

1

Отже, це залежить від того, яку версію 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/


1

Чи можете ви покращити цю відповідь, будь ласка, оскільки це я використовую, але я не на 100% зрозумілий. Це добре, але IntelliJ додав нову WeatherStation [0]. Чому 0?

    public WeatherStation[] removeElementAtIndex(WeatherStation[] array, int index)
    {
        List<WeatherStation> list = new ArrayList<WeatherStation>(Arrays.asList(array));
        list.remove(index);
        return list.toArray(new WeatherStation[0]);
    }


Чому ми повинні вдосконалювати ваше питання? Або ви знаєте відповідь, або не знаєте. Звичайно, слід надати відповідь, яка справді допомагає іншим, а не той, хто більше бентежить, ніж допомагає.
HimBromBeere

-2

використовувати два рядки коду для перетворення масиву в список, якщо ви використовуєте його в ціле значення, ви повинні використовувати тип автобоксингу для примітивного типу даних

  Integer [] arr={1,2};
  Arrays.asList(arr);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.