Konwertowanie tablicy na listę w Javie


1027

Jak przekonwertować tablicę na listę w Javie?

Użyłem, Arrays.asList()ale zachowanie (i podpis) jakoś zmieniło się z Java SE 1.4.2 (dokumenty są teraz w archiwum) na 8, a większość fragmentów znalezionych w Internecie używa zachowania 1.4.2.

Na przykład:

int[] spam = new int[] { 1, 2, 3 };
Arrays.asList(spam)
  • na 1.4.2 zwraca listę zawierającą elementy 1, 2, 3
  • w wersji 1.5.0+ zwraca listę zawierającą spam spamowy

W wielu przypadkach powinno być łatwe do wykrycia, ale czasami może się niepostrzeżenie wymknąć:

Assert.assertTrue(Arrays.asList(spam).indexOf(4) == -1);

20
Myślę, że twój przykład jest zepsuty Arrays.asList(new int[] { 1, 2, 3 }):; zdecydowanie nie skompilować w Java 1.4.2, ponieważ int[]jest nieObject[] .
— Joachim Sauer

1
Och, możesz mieć rację. Nie miałem kompilatora Java 1.4.2, aby przetestować mój przykład przed opublikowaniem. Teraz, po twoim komentarzu i odpowiedzi Joe, wszystko ma o wiele więcej sensu.
— Alexandru,

1
Myślałem, że Autoboxing obejmowałby konwersję z prymitywnej na otokową klasę całkowitą. Możesz najpierw wykonać rzutowanie, a następnie powyższy kod Arrays.asListpowinien działać.
— Koński głos

2
Stream.boxed () Java 8 zajmie się autoboxingiem i może być do tego użyty. Zobacz moją odpowiedź poniżej .
— Ibrahim Arief

Odpowiedzi:


1430

W twoim przykładzie dzieje się tak, ponieważ nie możesz mieć listy typu pierwotnego. Innymi słowy,List<int> nie jest to możliwe.

Możesz jednak List<Integer>użyć Integerklasy, która otacza intprymityw. Konwersja tablicy do Listze Arrays.asListsposobem gospodarczym.

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

Zobacz ten kod uruchamiany na żywo w IdeOne.com .


112
Lub nawet prościej: Arrays.asList (1, 2, 3);
— Kong

45
Skąd wie, żeby nie tworzyć List<Integer[]>?
— Thomas Ahle,

25
Nie działa w Javie 5+.
— djechlin

6
@ThomasAhle Nie tworzy List <Integer []> tworzy obiekt List <Integer>. A jeśli chcesz być bezpieczny, pisz: Tablice. <Integer> asList (spam);
— user1712376

6
@ThomasAhle To dobre pytanie. Domyślam się, że to tylko reguła w kompilatorze Java. Na przykład poniższy kod zwraca List <Integer []> Integer[] integerArray1 = { 1 }; Integer[] integerArray2 = { 2 }; List<Integer[]> integerArrays = Arrays.asList(integerArray1, integerArray2);
— Simon

167

W Javie 8 możesz używać strumieni:

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

To miłe, ale nie zadziała boolean[]. Myślę, że to dlatego, że tak samo łatwo jest zrobić Boolean[]. To prawdopodobnie lepsze rozwiązanie. W każdym razie to ciekawe dziwactwo.
— GlenPeterson

138

Mówiąc o sposobie konwersji, zależy to od tego, dlaczego potrzebujesz swojego List. Jeśli potrzebujesz tylko do odczytu danych. Ok, no to dajesz:

Integer[] values = { 1, 3, 7 };
List<Integer> list = Arrays.asList(values);

Ale jeśli zrobisz coś takiego:

list.add(1);

dostajesz java.lang.UnsupportedOperationException. Więc w niektórych przypadkach potrzebujesz tego:

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

Pierwsze podejście faktycznie nie konwertuje tablicy, ale „reprezentuje” ją jak List. Ale tablica jest pod maską i ma wszystkie swoje właściwości, takie jak stała liczba elementów. Pamiętaj, że musisz podać typ podczas konstruowania ArrayList.


1
„niezmienność” zmieszało mnie na chwilę. Możesz oczywiście zmienić wartości tablicy. Nie można jednak zmienić jego rozmiaru.
— Tim Pohlmann

125

Problem polega na tym, że varargs został wprowadzony w Javie 5 i niestety Arrays.asList()został również przeciążony wersją vararg. Tak Arrays.asList(spam)jest rozumiany przez kompilator Java5 jako parametr vararg tablic int.

Problem ten wyjaśniono bardziej szczegółowo w Effective Java 2nd Ed., Rozdział 7, pozycja 42.


4
Rozumiem, co się stało, ale nie dlaczego nie jest to udokumentowane. Szukam alternatywnego rozwiązania bez ponownego montażu koła.
— Alexandru

2
@UsmanIsmail Począwszy od Java 8, możemy używać strumieni do tej konwersji. Zobacz moją odpowiedź poniżej .
— Ibrahim Arief

109

Wydaje się, że trochę późno, ale oto moje dwa centy. Nie możemy mieć List<int>za intto prymitywny typ tak możemy mieć tylko List<Integer>.

Java 8 (tablica int)

int[] ints = new int[] {1,2,3,4,5};
List<Integer> list11 =Arrays.stream(ints).boxed().collect(Collectors.toList()); 

Java 8 i niższe (tablica liczb całkowitych)

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

Potrzebujesz ArrayList, a nie List?

Jeśli chcemy konkretnej implementacji Listnp. ArrayListMożemy użyć toCollectionjako:

ArrayList<Integer> list24 = Arrays.stream(integers)
                          .collect(Collectors.toCollection(ArrayList::new));

Dlaczego list21nie można modyfikować strukturalnie?

Kiedy używamy, Arrays.asListrozmiar zwracanej listy jest ustalony, ponieważ zwracana lista nie jest java.util.ArrayList, ale prywatną klasą statyczną zdefiniowaną w środku java.util.Arrays. Więc jeśli dodamy lub usuniemy elementy ze zwróconej listy, UnsupportedOperationExceptionzostanie wygenerowany znak „ an” . Więc powinniśmy iść, list22kiedy chcemy zmodyfikować listę. Jeśli mamy Javę 8, możemy również skorzystać z list23.

Dla jasności list21można zmodyfikować w tym sensie, że możemy wywoływać, list21.set(index,element)ale ta lista może nie być modyfikowana strukturalnie, tj. Nie może dodawać ani usuwać elementów z listy. Możesz również sprawdzić to pytanie .


Jeśli chcemy niezmienną listę, możemy ją zawinąć jako:

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

Inną kwestią do odnotowania jest to, że metoda Collections.unmodifiableList zwraca niemodyfikowalny widok podanej listy. Kolekcja niemodyfikowalna jest kolekcją niemodyfikowalną, a także widokiem na kolekcję podkładową. Należy pamiętać, że zmiany w kolekcji kopii zapasowych mogą być nadal możliwe, a jeśli wystąpią, są widoczne w widoku niemodyfikowalnym.

Możemy mieć naprawdę niezmienną listę w Javie 9 i 10.

Naprawdę niezmienna lista

Java 9:

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

Java 10 (lista prawdziwie niezmienna) na dwa sposoby:

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

Sprawdź również moją odpowiedź, aby uzyskać więcej.


@BasilBourque Miałem na myśli, że nie mogę modyfikować struktury listy poprzez dodawanie / usuwanie, ale mogę zmieniać elementy.
— akhil_mittal

Rzeczywiście, wypróbowałem trochę kodu i potwierdziłem, że wywoływanie List::addi List::removeniepowodzenie z listą zwróconą przez Arrays.asList. JavaDoc dla tej metody jest źle napisany i niejasny w tej kwestii. W trzecim czytaniu przypuszczam, że wyrażenie „o stałym rozmiarze” miało oznaczać, że nie można dodawać ani usuwać elementów.
— Basil Bourque,


11

Niedawno musiałem przekonwertować tablicę na listę. Później program przefiltrował listę próbując usunąć dane. Korzystając z funkcji Arrays.asList (tablica), tworzysz kolekcję o stałym rozmiarze: nie możesz ani dodawać, ani usuwać. Ten wpis wyjaśnia problem lepiej niż potrafię: Dlaczego otrzymuję UnsupportedOperationException podczas próby usunięcia elementu z listy? .

W końcu musiałem wykonać konwersję „ręczną”:

    List<ListItem> items = new ArrayList<ListItem>();
    for (ListItem item: itemsArray) {
        items.add(item);
    }

Przypuszczam, że mogłem dodać konwersję z tablicy do listy za pomocą operacji List.addAll (items).


11
new ArrayList<ListItem>(Arrays.asList(itemsArray))zrobiłby to samo
— Marco13

1
@BradyZhu: Przyznaję, że powyższa odpowiedź nie rozwiązuje mojego problemu z tablicą o stałym rozmiarze, ale w zasadzie mówisz tutaj o RTFM, która zawsze ma złą formę. Wyjaśnij, co jest nie tak z odpowiedzią lub nie zawracaj sobie głowy komentowaniem.
— Steve Gelman,

2
Narzędzia inspekcyjne mogą wyświetlać ostrzeżenie tutaj i podałeś przyczynę. Nie ma potrzeby ręcznego kopiowania elementów, użyj Collections.addAll(items, itemsArray)zamiast tego.
— Darek Kay

Po prostu traf ten wyjątek. Obawiam się, że odpowiedź Marco13 powinna być poprawną odpowiedzią. Być może będę musiał przejść przez cały rok, aby naprawić wszystkie wyjątki „asList”.

7

Korzystanie z tablic

Jest to najprostszy sposób na konwersję tablicy List. Jeśli jednak spróbujesz dodać nowy element lub usunąć istniejący element z listy, UnsupportedOperationExceptionzostanie wyrzucony.

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!

Korzystanie z ArrayList lub innych implementacji listy

forPętli można użyć do dodania wszystkich elementów tablicy do Listimplementacji, np . ArrayList:

List<Integer> list = new ArrayList<>();
for (int i : new int[]{1, 2, 3}) {
  list.add(i);
}

Korzystanie ze Stream API w Javie 8

Możesz przekształcić tablicę w strumień, a następnie zebrać strumień przy użyciu różnych kolektorów: Domyślny kolektor w Javie 8 jest używany ArrayListza ekranem, ale możesz także narzucić preferowaną implementację.

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

Zobacz też:


6

Kolejne obejście, jeśli używasz apache commons-lang:

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

Gdzie ArrayUtils.toObject konwertuje int[]naInteger[]


5

musisz rzucić się na tablicę

Arrays.asList((Object[]) array)

3
java: typy niezgodne: int [] nie można przekonwertować na java.lang.Object []
— dVaffection

@dVaffection Następnie rzutuj na int []. Ważną częścią jest rzutowanie na tablicę.
— Nebril

5

Jednowarstwowy:

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


5

Jeśli celujesz w Javę 8 (lub nowszą wersję), możesz spróbować:

int[] numbers = new int[] {1, 2, 3, 4};
List<Integer> integers = Arrays.stream(numbers)
                        .boxed().collect(Collectors.<Integer>toList());

UWAGA:

Zwróć uwagę na Collectors.<Integer>toList()tę ogólną metodę, która pozwala uniknąć błędu „Niezgodność typu: nie można przekonwertować z List<Object>na List<Integer>”.


4
  1. Używanie Guawy:

    Integer[] array = { 1, 2, 3};
    List<Integer> list = Lists.newArrayList(sourceArray);
  2. Korzystanie z kolekcji Apache Commons:

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

3

Jeśli to pomaga: miałem ten sam problem i po prostu napisałem ogólną funkcję, która pobiera tablicę i zwraca ArrayList tego samego typu o tej samej treści:

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

Co jeśli to nie pomoże? Co wtedy zrobiłeś? ... jk :)
— Sᴀᴍ Onᴇᴌᴀ

2

Biorąc pod uwagę tablicę:

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

Konwertowanie tablicy liczb całkowitych na listę liczb całkowitych

Jeden sposób: boxed () -> zwraca IntStream

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

Drugi sposób: zamapuj każdy element strumienia na liczbę całkowitą, a następnie zbierz

UWAGA: Korzystając z mapToObj, możesz ukryć każdy element int w strumieniu łańcucha, strumieniu znaków itp., Umieszczając i do (char) i

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

Konwertowanie jednego typu tablicy na inny typ Przykład:

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

1

To zależy od tego, którą wersję Java próbujesz-

Java 7

 Arrays.asList(1, 2, 3);

LUB

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

LUB

Integer[] arr = new Integer[] { 1, 2, 3 };
Arrays.asList(arr);

W Javie 8

int[] num = new int[] {1, 2, 3};
List<Integer> list = Arrays.stream(num)
                        .boxed().collect(Collectors.<Integer>toList())

Odniesienia - http://www.codingeek.com/java/how-to-convert-array-to-list-in-java/


1

Czy możesz poprawić tę odpowiedź, ponieważ tego używam, ale nie jestem w 100% jasny. Działa dobrze, ale IntelliJ dodał nową WeatherStation [0]. Dlaczego 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]);
    }


Dlaczego powinno się poprawić swoje pytanie? Albo znasz odpowiedź, albo nie. Powinieneś oczywiście udzielić odpowiedzi, która naprawdę pomaga innym, a nie takiej, która dezorientuje bardziej niż pomaga.
— HimBromBeere

-2

użyj dwóch linii kodu, aby przekonwertować tablicę na listę, jeśli użyjesz go w wartości całkowitej, musisz użyć typu autoboxing dla pierwotnego typu danych

  Integer [] arr={1,2};
  Arrays.asList(arr);
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.