varargs java generics variadic-functions

java 8 varargs



Problema de Varargs a ArrayList en Java (4)

No entiendo por qué lo siguiente no funciona:

public void doSomething(int... args){ List<Integer> broken = new ArrayList<Integer>(Arrays.asList(args)) }

Entiendo que el compilador convierte los "int ... args" en una matriz, por lo que el código anterior debería funcionar.

En lugar de trabajar, obtengo:

no se puede encontrar el símbolo símbolo: constructor ArrayList (java.util.List <int[] >) ubicación: clase java.util.ArrayList <java.lang.Integer >

Eso es extraño No estoy agregando una matriz a la lista de arreglos, estoy agregando cada elemento de la lista a la lista de matrices. ¿Que esta pasando?


En este caso, el autoboxing (conversión automática de int a Integer ) no funciona. Tienes que agregar cada int manualmente a la lista.

Si necesita un código así a menudo, considere usar commons lang que tiene org.apache.commons.lang.ArrayUtils.toObject(int[])


Tu puedes hacer

public void doSomething(int... args){ List<Integer> ints = new ArrayList<Integer>(args.length); for(int i: args) ints.add(i); }

o

public void doSomething(Integer... args){ List<Integer> ints = Arrays.asList(args); }


Java no puede autobloquear una matriz, solo valores individuales. Sugeriría cambiar la firma de su método a

public void doSomething(Integer... args)

Luego, el autoboxing tendrá lugar cuando se llame a doSomething , en lugar de intentar (y fallar) al llamar a Arrays.asList .

Lo que está sucediendo es que ahora Java está autoboxing cada valor individual a medida que se pasa a su función. Lo que intentabas hacer antes era pasar una int[] a Arrays.asList() , le Arrays.asList() a esa función que hiciera el autoboxing.

Pero el auto-boxing es implementado por el compilador, ve que usted necesitaba un objeto pero estaba pasando una primitiva, por lo que insertó automáticamente el código necesario para convertirlo en un objeto apropiado. La función Arrays.asList() ya se ha compilado y espera objetos, y el compilador no puede convertir un int[] en un Integer[] .

Al mover el autoboxing a los llamantes de su función, ha resuelto ese problema.


Puedes resolver esto usando Guava:

List<Integer> broken = new ArrayList<>(Ints.asList(args))

O con transmisiones:

List<Integer> broken = Arrays .stream(array) .boxed() .collect(Collectors.toCollection(ArrayList::new));