Varargs to ArrayList problem in Java
JavaGenericsVariadic FunctionsJava Problem Overview
I don't understand why the following does not work:
public void doSomething(int... args){
List<Integer> broken = new ArrayList<Integer>(Arrays.asList(args))
}
Its my understanding that the compiler converts the "int... args" to an array, so the above code should work.
Instead of working I get:
>cannot find symbol
>symbol: constructor ArrayList(java.util.List<int[]
>)
>location: class java.util.ArrayList<java.lang.Integer
>
Thats bizarre. I'm not adding an array to array list, I'm adding each element from the list to the arraylist. Whats going on?
Java Solutions
Solution 1 - Java
Java cannot autobox an array, only individual values. I would suggest changing your method signature to
public void doSomething(Integer... args)
Then the autoboxing will take place when calling doSomething
, rather than trying (and failing) when calling Arrays.asList
.
What is happening is Java is now autoboxing each individual value as it is passed to your function. What you were trying to do before was, by passing an int[]
to Arrays.asList()
, you were asking that function to do the autoboxing.
But autoboxing is implemented by the compiler -- it sees that you needed an object but were passing a primitive, so it automatically inserted the necessary code to turn it into an appropriate object. The Arrays.asList()
function has already been compiled and expects objects, and the compiler cannot turn an int[]
into an Integer[]
.
By moving the autoboxing to the callers of your function, you've solved that problem.
Solution 2 - Java
You can do
public void doSomething(int... args){
List<Integer> ints = new ArrayList<Integer>(args.length);
for(int i: args) ints.add(i);
}
or
public void doSomething(Integer... args){
List<Integer> ints = Arrays.asList(args);
}
Solution 3 - Java
You can solve this using Guava:
List<Integer> broken = new ArrayList<>(Ints.asList(args))
Or with streams:
List<Integer> broken = Arrays
.stream(array)
.boxed()
.collect(Collectors.toCollection(ArrayList::new));
Solution 4 - Java
In this case, autoboxing (automatic conversion from int
to Integer
) doesn't work. You have to add each int
manually to the list.
If you need code like that often, consider using commons lang which has org.apache.commons.lang.ArrayUtils.toObject(int[])