¿Cómo puedo convertir List<Integer> a int[] en Java? [duplicar]

Resuelto asked hace 15 años • 16 respuestas

¿Cómo puedo convertir un List<Integer>aint[] Java?

Estoy confundido porque List.toArray()en realidad devuelve un Object[], que no se puede convertir ni Integer[]a niint[] .

Ahora mismo estoy usando un bucle para hacerlo:

int[] toIntArray(List<Integer> list) {
  int[] ret = new int[list.size()];
  for(int i = 0; i < ret.length; i++)
    ret[i] = list.get(i);
  return ret;
}

¿Existe una mejor manera de hacer esto?

Esto es similar a la pregunta ¿Cómo puedo convertir int[] a Integer[] en Java? .

 avatar Jun 07 '09 03:06
Aceptado

Con las secuencias agregadas en Java 8 podemos escribir código como:

int[] example1 = list.stream().mapToInt(i->i).toArray();
// OR
int[] example2 = list.stream().mapToInt(Integer::intValue).toArray();

Proceso de pensamiento:

  • El simple Stream#toArraydevuelve una Object[]matriz, por lo que no es lo que queremos. Además, Stream#toArray(IntFunction<A[]> generator)lo que devuelve A[]no hace lo que queremos, porque el tipo genérico Ano puede representar el tipo primitivo.int

  • Por lo tanto, sería bueno tener algún tipo de flujo que estuviera diseñado para manejar tipos primitivos inten lugar del tipo de referencia como Integer, porque toArraylo más probable es que su método también devuelva una int[]matriz (devolver algo más como Object[]o incluso en un cuadro Integer[]no sería natural para int). Y afortunadamente Java 8 tiene esa corriente que esIntStream

  • Así que ahora lo único que tenemos que descubrir es cómo convertir nuestro Stream<Integer>(que será devuelto list.stream()) a ese shiny IntStream.

    La búsqueda rápida en la documentación Streammientras buscamos métodos que regresen IntStreamnos dirige a nuestra solución, que es mapToInt(ToIntFunction<? super T> mapper)el método. Todo lo que necesitamos hacer es proporcionar un mapeo desde Integerhasta int.

    Dado que ToIntFunctiones una interfaz funcional, también podemos proporcionar su instancia mediante lambda o referencia de método .

    De todos modos, para convertir Integer a int podemos usar, Integer#intValuepor lo que dentro mapToIntpodemos escribir:

    mapToInt( (Integer i) -> i.intValue() )
    

    (o algunos tal vez prefieran: mapToInt(Integer::intValue).)

    Pero se puede generar un código similar usando unboxing, ya que el compilador sabe que el resultado de esta lambda debe ser de tipo int(la lambda utilizada mapToIntes una implementación de la ToIntFunctioninterfaz que espera como cuerpo un método de tipo: int applyAsInt(T value)que se espera que devuelva un int) .

    Entonces podemos simplemente escribir:

    mapToInt((Integer i)->i)
    

    Además, dado que el compilador puede inferir el Integertipo in porque devuelve a , también podemos omitirlo, lo que nos deja con(Integer i)List<Integer>#stream()Stream<Integer>

    mapToInt(i -> i)
    
Pshemo avatar May 30 '2014 00:05 Pshemo

Desafortunadamente, no creo que realmente exista una mejor manera de hacer esto debido a la naturaleza del manejo que hace Java de tipos primitivos, boxeo, matrices y genéricos. En particular:

  • List<T>.toArrayno funcionará porque no hay conversión de Integeraint
  • No se puede usar intcomo argumento de tipo para genéricos, por lo que tendría que ser un intmétodo específico (o uno que usara la reflexión para hacer trucos desagradables).

Creo que hay bibliotecas que tienen versiones autogeneradas de este tipo de método para todos los tipos primitivos (es decir, hay una plantilla que se copia para cada tipo). Es feo, pero me temo que así es :(

Aunque la Arraysclase apareció antes de que llegaran los genéricos a Java, aún tendría que incluir todas las horribles sobrecargas si se introdujera hoy (suponiendo que desee utilizar matrices primitivas).

Jon Skeet avatar Jun 06 '2009 20:06 Jon Skeet