¿Cómo convertir una ArrayList que contiene enteros a primitive int array?

Estoy tratando de convertir una ArrayList que contiene objetos Integer en primitive int [] con la siguiente pieza de código, pero está generando un error de tiempo de comstackción. ¿Es posible convertir en Java?

List x = new ArrayList(); int[] n = (int[])x.toArray(int[x.size()]); 

Puede convertir, pero no creo que haya nada incorporado para hacerlo automáticamente:

 public static int[] convertIntegers(List integers) { int[] ret = new int[integers.size()]; for (int i=0; i < ret.length; i++) { ret[i] = integers.get(i).intValue(); } return ret; } 

(Tenga en cuenta que esto arrojará una NullPointerException si cualquiera de los integers o cualquier elemento dentro de él es null ).

EDITAR: según los comentarios, es posible que desee utilizar el iterador de la lista para evitar costos desagradables con listas como LinkedList :

 public static int[] convertIntegers(List integers) { int[] ret = new int[integers.size()]; Iterator iterator = integers.iterator(); for (int i = 0; i < ret.length; i++) { ret[i] = iterator.next().intValue(); } return ret; } 

Si está usando java-8 también hay otra manera de hacerlo.

 int[] arr = list.stream().mapToInt(i -> i).toArray(); 

Lo que hace es:

  • obteniendo un Stream de la lista
  • obtener un IntStream mapeando cada elemento a sí mismo (función de identidad), unboxing el valor int retenido por cada objeto Integer (hecho automáticamente desde Java 5)
  • obtener la matriz de int llamando a toArray

También puede llamar explícitamente intValue través de una referencia de método, es decir:

 int[] arr = list.stream().mapToInt(Integer::intValue).toArray(); 

También vale la pena mencionar que podría obtener una NullPointerException si tiene alguna referencia null en la lista. Esto podría evitarse fácilmente agregando una condición de filtrado a la línea de flujo de esta manera:

  //.filter(Objects::nonNull) also works int[] arr = list.stream().filter(i -> i != null).mapToInt(i -> i).toArray(); 

Ejemplo:

 List 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 tiene una clase ArrayUtils, que tiene un método toPrimitive () que hace exactamente esto.

 import org.apache.commons.lang.ArrayUtils; ... List list = new ArrayList(); list.add(new Integer(1)); list.add(new Integer(2)); int[] intArray = ArrayUtils.toPrimitive(list.toArray(new Integer[0])); 

Sin embargo, como demostró Jon, es bastante fácil hacerlo usted mismo en lugar de usar bibliotecas externas.

Google Guava

Google Guava proporciona una manera ordenada de hacerlo llamando a Ints.toArray .

 List list = ...; int[] values = Ints.toArray(list); 

Creo que iterar usando el iterador de la Lista es una mejor idea, ya que list.get(i) puede tener un rendimiento deficiente dependiendo de la implementación de la Lista:

 private int[] buildIntArray(List integers) { int[] ints = new int[integers.size()]; int i = 0; for (Integer n : integers) { ints[i++] = n; } return ints; } 

usar Dollar debería ser bastante simple:

 List list = $(5).toList(); // the list 0, 1, 2, 3, 4 int[] array = $($(list).toArray()).toIntArray(); 

Estoy planeando mejorar la DSL para eliminar la toArray() intermedia a toArray()

Si está utilizando colecciones de Eclipse , puede usar el método collectInt() para pasar de un contenedor de objetos a un contenedor int primitivo.

 List 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 puede convertir su ArrayList a FastList , puede deshacerse del adaptador.

 Assert.assertArrayEquals( new int[]{1, 2, 3, 4, 5}, Lists.mutable.with(1, 2, 3, 4, 5) .collectInt(i -> i).toArray()); 

Nota: soy un committer para colecciones de Eclipse.

Me sorprende que estimulemos los métodos personalizados únicos siempre que una biblioteca perfectamente buena y bien utilizada como Apache Commons ya haya resuelto el problema. Aunque la solución es trivial, si no absurda, es irresponsable alentar tal comportamiento debido al mantenimiento y la accesibilidad a largo plazo.

Solo ve con Apache Commons

Simplemente puede copiarlo en una matriz:

 int[] arr = new int[list.size()]; for(int i = 0; i < list.size(); i++) { arr[i] = list.get(i); } 

No muy elegante; pero, oye, funciona ...

Este segmento de código me funciona, prueba esto

 Integer[] arr = x.toArray(new Integer[x.size()]); 
  List list = new ArrayList(); 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()]); 

acceso arr como normal int[] .