Conversion d'un tableau en liste en Java

1028

Comment convertir un tableau en liste en Java?

J'ai utilisé le Arrays.asList()mais le comportement (et la signature) est en quelque sorte passé de Java SE 1.4.2 (les documents sont maintenant archivés) à 8 et la plupart des extraits que j'ai trouvés sur le Web utilisent le comportement 1.4.2.

Par exemple:

int[] spam = new int[] { 1, 2, 3 };
Arrays.asList(spam)
  • sur 1.4.2 renvoie une liste contenant les éléments 1, 2, 3
  • sur 1.5.0+ renvoie une liste contenant le spam du tableau

Dans de nombreux cas, il doit être facile à détecter, mais parfois il peut passer inaperçu:

Assert.assertTrue(Arrays.asList(spam).indexOf(4) == -1);
Alexandru
la source
20
Je pense que votre exemple est cassé Arrays.asList(new int[] { 1, 2, 3 }):; n'a certainement pas compilé en Java 1.4.2, car an int[]n'est pas un Object[].
Joachim Sauer
1
Oh, vous avez peut-être raison. Je n'avais pas de compilateur Java 1.4.2 pour tester mon exemple avant de poster. Maintenant, après votre commentaire et la réponse de Joe, tout est beaucoup plus logique.
Alexandru
1
Je pensais que Autoboxing aurait couvert la conversion de la classe Integer primitive en wrapper. Vous pouvez d'abord effectuer le cast vous-même, puis le code ci-dessus Arrays.asListdevrait fonctionner.
Horse Voice
2
Stream.boxed () de Java 8 se chargera de l'autoboxing et pourra être utilisé pour cela. Voir ma réponse ci-dessous .
Ibrahim Arief
Solution Java 8: stackoverflow.com/questions/2607289/…
akhil_mittal

Réponses:

1431

Dans votre exemple, c'est parce que vous ne pouvez pas avoir une liste de type primitif. En d'autres termes, ce List<int>n'est pas possible.

Vous pouvez cependant avoir une List<Integer>utilisation de la Integerclasse qui encapsule la intprimitive. Convertissez votre tableau en un Listavec la Arrays.asListméthode utilitaire.

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

Découvrez ce code en direct sur IdeOne.com .

Joe Daley
la source
112
Ou encore plus simple: Arrays.asList (1, 2, 3);
Kong
45
Comment sait-il ne pas en créer un List<Integer[]>?
Thomas Ahle
25
Échoue en Java 5+.
djechlin
6
@ThomasAhle Il ne crée pas un List <Integer []> il crée un objet List <Integer>. Et si vous voulez être sûr du type, vous écrivez: Tableaux. <Integer> asList (spam);
user1712376
6
@ThomasAhle C'est une bonne question. Une supposition, c'est juste une règle dans le compilateur java. Par exemple, le code suivant renvoie un List <Integer []> Integer[] integerArray1 = { 1 }; Integer[] integerArray2 = { 2 }; List<Integer[]> integerArrays = Arrays.asList(integerArray1, integerArray2);
Simon
167

Dans Java 8, vous pouvez utiliser des flux:

int[] spam = new int[] { 1, 2, 3 };
Arrays.stream(spam)
      .boxed()
      .collect(Collectors.toList());
Ibrahim Arief
la source
C'est bien, mais ça ne marchera pas boolean[]. Je suppose que c'est parce qu'il est tout aussi facile de faire un Boolean[]. C'est probablement une meilleure solution. Quoi qu'il en soit, c'est une bizarrerie intéressante.
GlenPeterson
138

En parlant de conversion, cela dépend de la raison pour laquelle vous en avez besoin List. Si vous en avez besoin juste pour lire les données. OK, c'est parti:

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

Mais si vous faites quelque chose comme ça:

list.add(1);

vous obtenez java.lang.UnsupportedOperationException. Donc, dans certains cas, vous en avez même besoin:

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

La première approche ne convertit pas réellement le tableau mais le «représente» comme un List. Mais le tableau est sous le capot avec toutes ses propriétés comme un nombre fixe d'éléments. Veuillez noter que vous devez spécifier le type lors de la construction ArrayList.

Roman Nikitchenko
la source
1
"l'immuabilité" m'a un peu dérouté. Vous pouvez évidemment changer les valeurs du tableau. Vous ne pouvez cependant pas changer sa taille.
Tim Pohlmann
125

Le problème est que varargs a été introduit dans Java5 et malheureusement, Arrays.asList() surchargé avec une version vararg aussi. Ainsi Arrays.asList(spam)est compris par le compilateur Java5 comme un paramètre vararg des tableaux int.

Ce problème est expliqué plus en détail dans Effective Java 2nd Ed., Chapter 7, Item 42.

Péter Török
la source
4
Je comprends ce qui s'est passé, mais pas pourquoi cela n'est pas documenté. Je recherche une solution alternative sans réimplémenter la roue.
Alexandru
2
@UsmanIsmail Depuis Java 8, nous pouvons utiliser des flux pour cette conversion. Voir ma réponse ci-dessous .
Ibrahim Arief
109

Il semble peu tard mais voici mes deux cents. Nous ne pouvons pas avoir List<int>comme intun type primitif, nous ne pouvons donc que l'avoir List<Integer>.

Java 8 (tableau int)

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

Java 8 et versions antérieures (tableau entier)

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

Besoin d'ArrayList et non de List?

Dans le cas où nous voulons une implémentation spécifique, Listpar exemple, ArrayListnous pouvons utiliser toCollectioncomme:

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

Pourquoi list21ne peut - on pas être modifié structurellement?

Lorsque nous utilisons Arrays.asListla taille de la liste retournée est fixe car la liste retournée ne l'est pas java.util.ArrayList, mais une classe statique privée définie à l'intérieur java.util.Arrays. Donc, si nous ajoutons ou supprimons des éléments de la liste retournée, un UnsupportedOperationExceptionsera levé. Nous devons donc aller avec list22quand nous voulons modifier la liste. Si nous avons Java8, nous pouvons également y aller list23.

Pour être clair, cela list21peut être modifié dans le sens que nous pouvons appeler, list21.set(index,element)mais cette liste peut ne pas être structurellement modifiée, c'est-à-dire qu'elle ne peut pas ajouter ou supprimer des éléments de la liste. Vous pouvez également vérifier cette question .


Si nous voulons une liste immuable, nous pouvons l'envelopper comme suit:

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

Un autre point à noter est que la méthode Collections.unmodifiableList retourne une vue non modifiable de la liste spécifiée. Une collection de vues non modifiables est une collection non modifiable et est également une vue sur une collection de supports. Notez que des modifications de la collection de supports peuvent toujours être possibles et si elles se produisent, elles sont visibles à travers la vue non modifiable.

Nous pouvons avoir une liste vraiment immuable en Java 9 et 10.

Liste véritablement immuable

Java 9:

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

Java 10 (liste véritablement immuable) de deux manières:

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

Consultez également ma réponse pour en savoir plus.

akhil_mittal
la source
@BasilBourque Je voulais dire ne peut pas modifier la structure de la liste par ajout / suppression mais peut changer les éléments.
akhil_mittal
En effet, j'ai essayé du code et confirmé que l'appel List::add& List::removeéchoue avec une liste retournée par Arrays.asList. Le JavaDoc pour cette méthode est mal écrit et peu clair sur ce point. À ma troisième lecture, je suppose que l'expression «de taille fixe» voulait dire que l'on ne peut pas ajouter ou supprimer des éléments.
Basil Bourque
12

Encore plus court:

List<Integer> list = Arrays.asList(1, 2, 3, 4);
Vitaliy Sokolov
la source
11

J'ai récemment dû convertir un tableau en liste. Plus tard, le programme a filtré la liste en essayant de supprimer les données. Lorsque vous utilisez la fonction Arrays.asList (array), vous créez une collection de taille fixe: vous ne pouvez ni ajouter ni supprimer. Cette entrée explique le problème mieux que moi: pourquoi est-ce que j'obtiens une exception UnsupportedOperationException lorsque j'essaie de supprimer un élément d'une liste?.

Au final, j'ai dû faire une conversion "manuelle":

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

Je suppose que j'aurais pu ajouter la conversion d'un tableau à une liste en utilisant une opération List.addAll (items).

Steve Gelman
la source
11
new ArrayList<ListItem>(Arrays.asList(itemsArray))serait le même
Marco13
1
@BradyZhu: Certes, la réponse ci-dessus ne résout pas mon problème avec le tableau de taille fixe, mais vous dites essentiellement RTFM ici, ce qui est toujours une mauvaise forme. Veuillez expliquer ce qui ne va pas avec la réponse ou ne prenez pas la peine de commenter.
Steve Gelman
2
Les outils d'inspection peuvent afficher un avertissement ici, et vous en avez nommé la raison. Il n'est pas nécessaire de copier les éléments manuellement, utilisez Collections.addAll(items, itemsArray)plutôt.
Darek Kay
Frappez juste cette exception. Je crains que la réponse de Marco13 ne soit la bonne. Je devrai peut-être parcourir le code de l'année entière pour corriger toutes les exceptions "asList".
7

Utilisation de tableaux

C'est le moyen le plus simple de convertir un tableau en List. Cependant, si vous essayez d'ajouter un nouvel élément ou de supprimer un élément existant de la liste, un UnsupportedOperationExceptionsera levé.

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!

Utilisation d'ArrayList ou d'autres implémentations de liste

Vous pouvez utiliser une forboucle pour ajouter tous les éléments du tableau dans une Listimplémentation, par exemple ArrayList:

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

Utilisation de l'API Stream dans Java 8

Vous pouvez transformer le tableau en flux, puis collecter le flux à l'aide de différents collecteurs: le collecteur par défaut dans Java 8 utilise ArrayListderrière l'écran, mais vous pouvez également imposer votre implémentation préférée.

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

Voir également:

Mincong Huang
la source
6

Une autre solution de contournement si vous utilisez apache commons-lang:

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

ArrayUtils.toObject se convertit int[]enInteger[]

alaster
la source
5

vous devez lancer dans le tableau

Arrays.asList((Object[]) array)
Giancarlo Frison
la source
3
java: types incompatibles: int [] ne peut pas être converti en java.lang.Object []
dVaffection
@dVaffection Ensuite, transtypez en int []. La partie importante est de convertir un tableau.
Nebril
5

Bon mot:

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

Dans Java 9, vous avez la solution encore plus élégante d'utiliser des listes immuables via la nouvelle méthode de fabrique de commodité List.of:

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

(copié sans vergogne d' ici )

Pierluigi Vernetto
la source
Pour info, pour en savoir plus sur les détails techniques derrière cela, voir JEP 269: Convenience Factory Methods for Collections et une conférence de Stuart Marks , l'auteur principal.
Basil Bourque
5

Si vous ciblez Java 8 (ou version ultérieure), vous pouvez essayer ceci:

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

REMARQUE:

Faites attention à la Collectors.<Integer>toList(), cette méthode générique vous aide à éviter l'erreur "Non-correspondance de type: impossible de convertir de List<Object>à List<Integer>".

nybon
la source
4
  1. Utilisation de la goyave:

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

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

Si cela aide: J'ai eu le même problème et j'ai simplement écrit une fonction générique qui prend un tableau et retourne une ArrayList du même type avec le même contenu:

public static <T> ArrayList<T> ArrayToArrayList(T[] array) {
    ArrayList<T> list = new ArrayList<T>();
    for(T elmt : array) list.add(elmt);
    return list;
}
kleines filmröllchen
la source
Et si ça n'aide pas? Alors qu'est-ce que tu as fait ?? ... jk :)
Sᴀᴍ Onᴇᴌᴀ
2

Étant donné le tableau:

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

Conversion d'un tableau d'entiers en liste d'entiers

One way: boxed () -> retourne l'IntStream

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

Deuxième façon: mappez chaque élément du flux en entier, puis collectez

REMARQUE: En utilisant mapToObj, vous pouvez convertir chaque élément int en flux de chaînes, flux de caractères, etc. en mettant i dans (char) i

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

Conversion d'un type de tableau en un autre type Exemple:

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

Cela dépend donc de la version Java que vous essayez-

Java 7

 Arrays.asList(1, 2, 3);

OU

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

OU

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

Dans Java 8

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

Référence - http://www.codingeek.com/java/how-to-convert-array-to-list-in-java/

Hitesh Garg
la source
1

Pouvez-vous améliorer cette réponse s'il vous plaît car c'est ce que j'utilise mais je ne suis pas clair à 100%. Cela fonctionne bien mais intelliJ a ajouté une nouvelle WeatherStation [0]. Pourquoi le 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]);
    }

DevilCode
la source
Pourquoi devrions- nous améliorer votre question? Soit vous connaissez la réponse, soit vous ne le savez pas. Vous devez bien sûr fournir une réponse qui aide vraiment les autres, pas une qui dérange plus qu'elle n'aide.
HimBromBeere
-2

utilisez deux lignes de code pour convertir le tableau en liste si vous l'utilisez en valeur entière, vous devez utiliser le type de zone automatique pour le type de données primitif

  Integer [] arr={1,2};
  Arrays.asList(arr);
yousef
la source