Conversione di array in elenco in Java


1028

Come faccio a convertire un array in un elenco in Java?

Ho usato il Arrays.asList()ma il comportamento (e la firma) in qualche modo cambiato da Java SE 1.4.2 (documenti ora in archivio) a 8 e la maggior parte dei frammenti che ho trovato sul web usano il comportamento 1.4.2.

Per esempio:

int[] spam = new int[] { 1, 2, 3 };
Arrays.asList(spam)
  • su 1.4.2 restituisce un elenco contenente gli elementi 1, 2, 3
  • su 1.5.0+ restituisce un elenco contenente lo spam dell'array

In molti casi dovrebbe essere facile da rilevare, ma a volte può scivolare inosservato:

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

20
Penso che il tuo esempio sia rotto Arrays.asList(new int[] { 1, 2, 3 }):; sicuramente non compilato in Java 1.4.2, perché an nonint[] è un . Object[]
Joachim Sauer,

1
Oh, potresti avere ragione. Non avevo un compilatore Java 1.4.2 in giro per testare il mio esempio prima di pubblicare. Ora, dopo il tuo commento e la risposta di Joe, tutto ha molto più senso.
Alexandru,

1
Ho pensato che Autoboxing avrebbe coperto la conversione dalla classe integer primitiva a wrapper. Puoi fare tu stesso il cast prima e poi il codice sopra Arrays.asListdovrebbe funzionare.
Horse Voice

2
Stream.boxed () di Java 8 si occuperà del box automatico e può essere usato per questo. Vedi la mia risposta qui sotto .
Ibrahim Arief,

Risposte:


1431

Nel tuo esempio, è perché non puoi avere un Elenco di un tipo primitivo. In altre parole, List<int>non è possibile.

Tuttavia, è possibile List<Integer>utilizzare una Integerclasse che avvolge la intprimitiva. Converti l'array in a Listcon il Arrays.asListmetodo utility.

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

Vedi questo codice eseguito dal vivo su IdeOne.com .


112
O ancora più semplice: Arrays.asList (1, 2, 3);
Kong,

45
Come fa a non creare un List<Integer[]>?
Thomas Ahle,

25
Errore in Java 5+.
Djechlin,

6
@ThomasAhle Non crea un Elenco <Integer []> crea un oggetto List <Integer>. E se vuoi essere sicuro, scrivi: Arrays. <Integer> asList (spam);
user1712376,

6
@ThomasAhle Questa è una buona domanda. Suppongo sia solo una regola nel compilatore Java. Ad esempio, il codice seguente restituisce un Elenco <Numero intero []> Integer[] integerArray1 = { 1 }; Integer[] integerArray2 = { 2 }; List<Integer[]> integerArrays = Arrays.asList(integerArray1, integerArray2);
Simon,

167

In Java 8, è possibile utilizzare i flussi:

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

Questo è carino, ma non funzionerà boolean[]. Immagino che sia perché è altrettanto facile fare un Boolean[]. Questa è probabilmente una soluzione migliore. Comunque, è una stranezza interessante.
GlenPeterson,

138

Parlando del modo di conversione, dipende dal motivo per cui hai bisogno del tuo List. Se ne hai bisogno solo per leggere i dati. OK, eccoti qui:

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

Ma poi se fai qualcosa del genere:

list.add(1);

hai capito java.lang.UnsupportedOperationException. Quindi per alcuni casi hai persino bisogno di questo:

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

Il primo approccio in realtà non converte l'array ma lo "rappresenta" come un List. Ma la matrice è sotto il cofano con tutte le sue proprietà come il numero fisso di elementi. Si noti che è necessario specificare il tipo durante la costruzione ArrayList.


1
l '"immutabilità" mi ha confuso per un momento. È ovviamente possibile modificare i valori dell'array. Tuttavia, non puoi modificarne le dimensioni.
Tim Pohlmann,

125

Il problema è che varargs è stato introdotto in Java5 e sfortunatamente, è Arrays.asList()stato sovraccaricato anche con una versione vararg. Quindi Arrays.asList(spam)è inteso dal compilatore Java5 come un parametro vararg di array int.

Questo problema è spiegato in maggior dettaglio in 2a edizione effettiva di Java, capitolo 7, punto 42.


4
Capisco cosa è successo, ma non perché non sia documentato. Sto cercando una soluzione alternativa senza reimplementare la ruota.
Alexandru,

2
@UsmanIsmail A partire da Java 8, possiamo usare gli stream per questa conversione. Vedi la mia risposta qui sotto .
Ibrahim Arief,

109

Sembra un po 'tardi ma ecco i miei due centesimi. Non possiamo avere List<int>come intè un tipo primitivo, quindi possiamo solo avereList<Integer> .

Java 8 (int array)

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

Java 8 e precedenti (array intero)

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

Hai bisogno di ArrayList e non di List?

Nel caso in cui desideriamo un'implementazione specifica, Listad esempio ArrayList, possiamo usare toCollectioncome:

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

Perché list21non può essere modificato strutturalmente?

Quando utilizziamo Arrays.asListla dimensione dell'elenco restituito viene riparato perché l'elenco restituito non lo è java.util.ArrayList, ma una classe statica privata definita all'interno java.util.Arrays. Quindi, se aggiungiamo o rimuoviamo elementi dall'elenco restituito, UnsupportedOperationExceptionverrà lanciato un. Quindi dovremmo andare con list22quando vogliamo modificare l'elenco. Se abbiamo Java8, allora possiamo anche andare conlist23 .

Per essere chiari list21può essere modificato nel senso che possiamo chiamare list21.set(index,element)ma questo elenco potrebbe non essere modificato strutturalmente, cioè non è possibile aggiungere o rimuovere elementi dall'elenco. Puoi anche controllare questa domanda .


Se vogliamo un elenco immutabile, possiamo inserirlo come segue:

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

Un altro punto da notare è che il metodo Collections.unmodifiableListrestituisce una vista non modificabile dell'elenco specificato. Una raccolta di viste non modificabile è una raccolta non modificabile ed è anche una vista su una raccolta di supporto. Si noti che le modifiche alla raccolta di backup potrebbero essere ancora possibili e, se si verificano, sono visibili attraverso la vista non modificabile.

Possiamo avere un elenco davvero immutabile in Java 9 e 10.

Elenco veramente immutabile

Java 9:

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

Java 10 (Elenco veramente immutabile) in due modi:

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

Controlla anche questa mia risposta per ulteriori informazioni.


@BasilBourque Volevo dire che non è possibile modificare la struttura dell'elenco mediante aggiunta / eliminazione, ma può cambiare gli elementi.
akhil_mittal

In effetti, ho provato un po 'di codice e ha confermato che chiamare List::adde List::removenon con una lista restituita da Arrays.asList. JavaDoc per quel metodo è scritto male e non è chiaro su questo punto. Alla mia terza lettura, suppongo che la frase "dimensione fissa" significasse dire che non è possibile aggiungere o rimuovere elementi.
Basil Bourque,


11

Di recente ho dovuto convertire un array in un elenco. Successivamente il programma ha filtrato l'elenco tentando di rimuovere i dati. Quando si utilizza la funzione Arrays.asList (array), si crea una raccolta di dimensioni fisse: non è possibile né aggiungere né eliminare. Questa voce spiega il problema meglio di me: Perché ottengo UnsupportedOperationException quando provo a rimuovere un elemento da un elenco? .

Alla fine, ho dovuto fare una conversione "manuale":

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

Suppongo che avrei potuto aggiungere la conversione da un array a un elenco usando un'operazione List.addAll (articoli).


11
new ArrayList<ListItem>(Arrays.asList(itemsArray))sarebbe lo stesso
Marco13

1
@BradyZhu: Concesso la risposta sopra non risolve il mio problema con l'array di dimensioni fisse, ma sostanzialmente stai dicendo RTFM qui, che è sempre una cattiva forma. Spiega cosa non va nella risposta o non preoccuparti di commentare.
Steve Gelman,

2
Gli strumenti di ispezione possono mostrare un avviso qui e tu hai indicato il motivo. Non è necessario copiare gli elementi manualmente, utilizzare Collections.addAll(items, itemsArray)invece.
Darek Kay,

Basta colpire questa eccezione. Temo che la risposta di Marco13 dovrebbe essere la risposta corretta. Potrebbe essere necessario passare attraverso il codice per l'intero anno per correggere tutte le eccezioni "asList".

7

Utilizzo di array

Questo è il modo più semplice per convertire un array in List. Tuttavia, se si tenta di aggiungere un nuovo elemento o rimuovere un elemento esistente dall'elenco, UnsupportedOperationExceptionverrà generato un.

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!

Utilizzo di ArrayList o altre implementazioni di elenchi

È possibile utilizzare un forciclo per aggiungere tutti gli elementi dell'array in Listun'implementazione, ad esempio ArrayList:

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

Utilizzo dell'API Stream in Java 8

Puoi trasformare l'array in un flusso, quindi raccogliere il flusso utilizzando diversi raccoglitori: il raccoglitore predefinito in Java 8 utilizza ArrayListdietro lo schermo, ma puoi anche imporre l'implementazione preferita.

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

Guarda anche:


6

Un'altra soluzione alternativa se si utilizza apache commons-lang:

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

Dove ArrayUtils.toObject convertiti int[]aInteger[]


5

devi eseguire il cast in array

Arrays.asList((Object[]) array)

3
java: tipi incompatibili: int [] non può essere convertito in java.lang.Object []
dVaffection il

@dVaffection Quindi cast in int []. La parte importante è eseguire il cast su un array.
Nebril,

5

One-liner:

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


5

Se stai scegliendo come target Java 8 (o successivo), puoi provare questo:

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

NOTA:

Prestare attenzione a Collectors.<Integer>toList(), questo metodo generico consente di evitare l'errore "Tipo non corrispondente: impossibile convertire da List<Object>in List<Integer>".


4
  1. Utilizzando Guava:

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

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

3

Se questo aiuta: ho avuto lo stesso problema e ho semplicemente scritto una funzione generica che accetta un array e restituisce un ArrayList dello stesso tipo con lo stesso contenuto:

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

E se non fosse d'aiuto? Allora cosa hai fatto ?? ... jk :)
Sᴀᴍ Onᴇᴌᴀ,

2

Array dato:

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

Conversione di array di numeri interi in Elenco numeri interi

Un modo: boxed () -> restituisce IntStream

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

Secondo modo: mappa ogni elemento del flusso su Intero e poi raccogli

NOTA: utilizzando mapToObj è possibile convertire ciascun elemento int in stream string, char stream ecc. Inserendo i in (char) i

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

Conversione di un tipo di array in un altro tipo Esempio:

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

1

Quindi dipende da quale versione Java stai provando-

Java 7

 Arrays.asList(1, 2, 3);

O

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

O

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

In Java 8

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

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


1

Puoi migliorare questa risposta, per favore, dato che questo è quello che uso ma non sono chiaro al 100%. Funziona bene ma intelliJ ha aggiunto la nuova WeatherStation [0]. Perché lo 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]);
    }


Perché dovremmo noi migliorare la tua domanda? O conosci la risposta o no. Ovviamente dovresti fornire una risposta che aiuti davvero gli altri, non uno che confonde più di quanto aiuti.
HimBromBeere

-2

utilizzare due righe di codice per convertire l'array in elenco se lo si utilizza in un valore intero, è necessario utilizzare il tipo di autoboxing per il tipo di dati primitivo

  Integer [] arr={1,2};
  Arrays.asList(arr);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.