Comment convertir un ArrayList contenant des entiers en tableau int primitif?
j'essaie de convertir un ArrayList contenant des objets entiers en int primitif[] avec le morceau de code suivant, mais il lance erreur de temps de compilation. Est-il possible de convertir en Java?
List<Integer> x = new ArrayList<Integer>();
int[] n = (int[])x.toArray(int[x.size()]);
12 réponses
vous pouvez convertir, mais je ne pense pas qu'il y ait quoi que ce soit intégré pour le faire automatiquement:
public static int[] convertIntegers(List<Integer> integers)
{
int[] ret = new int[integers.size()];
for (int i=0; i < ret.length; i++)
{
ret[i] = integers.get(i).intValue();
}
return ret;
}
(notez que cela lancera une NullPointerException si integers
ou tout élément à l'intérieur de celui-ci est null
.)
modifier: comme par les commentaires, vous pouvez vouloir utiliser l'itérateur de liste pour éviter des coûts désagréables avec des listes telles que LinkedList
:
public static int[] convertIntegers(List<Integer> integers)
{
int[] ret = new int[integers.size()];
Iterator<Integer> iterator = integers.iterator();
for (int i = 0; i < ret.length; i++)
{
ret[i] = iterator.next().intValue();
}
return ret;
}
si vous utilisez java-8 il y a aussi une autre façon de le faire.
int[] arr = list.stream().mapToInt(i -> i).toArray();
Ce qu'il fait est:
- obtention d'un
Stream<Integer>
dans la liste - obtention d'un
IntStream
par mise en correspondance de chaque élément avec lui-même (fonction d'identité), déboxage de la valeurint
retenue par chaqueInteger
objet (fait automatiquement depuis Java 5) - obtenir le tableau de
int
en appelanttoArray
vous pouvez aussi explicitement appeler intValue
via une référence de méthode, I. e:
int[] arr = list.stream().mapToInt(Integer::intValue).toArray();
il est également intéressant de mentionner que vous pouvez obtenir un NullPointerException
si vous avez une référence null
dans la liste. Cela pourrait être facilement évité en ajoutant une condition de filtrage au pipeline de flux comme ceci:
//.filter(Objects::nonNull) also works
int[] arr = list.stream().filter(i -> i != null).mapToInt(i -> i).toArray();
exemple:
List<Integer> list = Arrays.asList(1, 2, 3, 4);
int[] arr = list.stream().mapToInt(i -> i).toArray(); //[1, 2, 3, 4]
list.set(1, null); //[1, null, 3, 4]
arr = list.stream().filter(i -> i != null).mapToInt(i -> i).toArray(); //[1, 3, 4]
Apache Commons a une classe ArrayUtils, qui a une méthode toPrimitive() qui fait exactement cela.
import org.apache.commons.lang.ArrayUtils;
...
List<Integer> list = new ArrayList<Integer>();
list.add(new Integer(1));
list.add(new Integer(2));
int[] intArray = ArrayUtils.toPrimitive(list.toArray(new Integer[0]));
Cependant, comme Jon l'a montré, il est assez facile de le faire par vous-même au lieu d'utiliser des bibliothèques externes.
Google Guava
Google Guava fournit une façon soignée de le faire en appelant Ints.toArray
.
List<Integer> list = ...;
int[] values = Ints.toArray(list);
je pense que l'itération en utilisant l'itérateur de la liste est une meilleure idée, car list.get(i)
peut avoir de mauvaises performances en fonction de la mise en œuvre de la liste:
private int[] buildIntArray(List<Integer> integers) {
int[] ints = new int[integers.size()];
int i = 0;
for (Integer n : integers) {
ints[i++] = n;
}
return ints;
}
si vous utilisez Eclipse Collections , vous pouvez utiliser la méthode collectInt()
pour passer d'un conteneur objet à un conteneur int primitif.
List<Integer> integers = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
MutableIntList intList =
ListAdapter.adapt(integers).collectInt(i -> i);
Assert.assertArrayEquals(new int[]{1, 2, 3, 4, 5}, intList.toArray());
Si vous pouvez convertir votre ArrayList
à un FastList
, vous pouvez vous débarrasser de l'adaptateur.
Assert.assertArrayEquals(
new int[]{1, 2, 3, 4, 5},
Lists.mutable.with(1, 2, 3, 4, 5)
.collectInt(i -> i).toArray());
Note: je suis un committer pour les collections Eclipse.
cela me déconcerte que nous encouragions des méthodes personnalisées uniques chaque fois qu'une bibliothèque parfaitement bonne, bien utilisée comme Apache Commons a déjà résolu le problème. Si la solution est triviale si pas absurde, il est irresponsable d'encourager un tel comportement à long terme de maintenance et d'accessibilité.
Juste aller avec Apache Commons
vous pouvez simplement le copier dans un tableau:
int[] arr = new int[list.size()];
for(int i = 0; i < list.size(); i++) {
arr[i] = list.get(i);
}
pas trop chic, mais ça marche...
ce segment de code fonctionne pour moi, essayez
Integer[] arr = x.toArray(new Integer[x.size()]);
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
int[] result = null;
StringBuffer strBuffer = new StringBuffer();
for (Object o : list) {
strBuffer.append(o);
result = new int[] { Integer.parseInt(strBuffer.toString()) };
for (Integer i : result) {
System.out.println(i);
}
strBuffer.delete(0, strBuffer.length());
}
Integer[] arr = (Integer[]) x.toArray(new Integer[x.size()]);
accès arr
comme d'habitude int[]
.