J'ai vu la question: Créer ArrayList à partir d'un tablea
Cependant, lorsque j'essaie cette solution avec le code suivant, cela ne fonctionne pas tout à fait dans tous les cas:
import Java.util.ArrayList;
import Java.util.Arrays;
import Java.util.Collection;
import Java.util.List;
public class ToArrayList {
public static void main(String[] args) {
// this works
String[] elements = new String[] { "Ryan", "Julie", "Bob" };
List<String> list = new ArrayList<String>(Arrays.asList(elements));
System.out.println(list);
// this works
List<Integer> intList = null;
intList = Arrays.asList(3, 5);
System.out.println(intList);
int[] intArray = new int[] { 0, 1 };
// this doesn't work!
intList = new ArrayList<Integer>(Arrays.asList(intArray));
System.out.println(intList);
}
}
Qu'est-ce que je fais mal ici? Le code intList = new ArrayList<Integer>(Arrays.asList(intArray));
ne devrait-il pas être compilé correctement?
Le problème
intList = new ArrayList<Integer>(Arrays.asList(intArray));
est-ce int[]
est considéré comme une seule instance Object
car un tableau primitif s'étend de Object
. Cela fonctionnerait si vous avez Integer[]
au lieu de int[]
puisque vous envoyez maintenant un tableau de Object
.
Integer[] intArray = new Integer[] { 0, 1 };
//now you're sending a Object array
intList = new ArrayList<Integer>(Arrays.asList(intArray));
D'après votre commentaire: si vous souhaitez toujours utiliser un int[]
(ou un autre tableau de type primitif) en tant que données principales, vous devez ensuite créer un tableau supplémentaire avec la classe wrapper. Pour cet exemple:
int[] intArray = new int[] { 0, 1 };
Integer[] integerArray = new Integer[intArray.length];
int i = 0;
for(int intValue : intArray) {
integerArray[i++] = intValue;
}
intList = new ArrayList<Integer>(Arrays.asList(integerArray));
Mais comme vous utilisez déjà une boucle for
, cela ne me dérangerait pas d'utiliser un tableau de classe de wrapper temporaire, ajoutez simplement vos éléments directement dans la liste:
int[] intArray = new int[] { 0, 1 };
intList = new ArrayList<Integer>();
for(int intValue : intArray) {
intList.add(intValue);
}
Avec Java 8 vous pouvez le faire en une seule ligne:
int [] intArr = {1, 1, 2, 3, 5, 8, 11}; List <Integer> list = Arrays.stream (intArr) .boxed (). Collect (Collectors.toList ()); list.forEach (System.out :: println);
Cela ne fonctionne pas car vous utilisez un int[]
au lieu de Integer[]
. Essaye ça:
Integer[] intArray = new Integer[] { 0, 1 };
// this should work now
intList = new ArrayList<Integer>(Arrays.asList(intArray));
Le problème concerne la Autoboxing. Java convertit automatiquement int
en Integer
automatiquement, mais il ne convertit pas int[]
à Integer[]
. D'où la raison.
public static <T> List<T> asList(T... a)
asList
est défini comme ci-dessus. Il attend un vararg de type T
. c'est-à-dire qu'il peut prendre un tableau d'objets de type T
. Dans votre cas, car Java ne peut pas convertir int[]
à Integer[]
, donc il prend le type T
comme int[]
plutôt que Integer
comme vous le souhaitez. Vous obtenez donc une liste de type List<int[]
. Vous devrez le convertir manuellement en `Integer[]
de int[]
Il y a un excellent article dans le livre Effective Java
par Joshua Bloch où il explique les fosses avec varargs et c'est l'un d'entre eux.
La collection veut que les objets et les primitives ne dérivent pas de l'objet. donc Integer
autorise mais int
n'est pas autorisé.
Vous devez donc utiliser la classe wrapper Integer
au lieu de int
qui est de type primitif.
Juste un exemple:
Integer[] intArray = new Integer[] { 0, 1 };
intList = new ArrayList<Integer>(Arrays.asList(intArray));