Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Varargs to ArrayList problem in Java

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?

like image 815
Ben B. Avatar asked Mar 18 '11 13:03

Ben B.


People also ask

Is it good to use varargs in Java?

Varargs are useful for any method that needs to deal with an indeterminate number of objects. One good example is String. format . The format string can accept any number of parameters, so you need a mechanism to pass in any number of objects.

Can I pass ArrayList to Varargs Java?

Passing an ArrayList to method expecting vararg as parameter To do this we need to convert our ArrayList to an Array and then pass it to method expecting vararg. We can do this in single line i.e. * elements passed.

What is the rule for using varargs in Java?

While using the varargs, you must follow some rules otherwise program code won't compile. The rules are as follows: There can be only one variable argument in the method. Variable argument (varargs) must be the last argument.

Is Java Varargs an array?

Every time we use varargs, the Java compiler creates an array to hold the given parameters. In this case, the compiler creates an array with generic type components to hold the arguments. The varargs usage is safe if and only if: We don't store anything in the implicitly created array.


2 Answers

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.

like image 144
Jonathan Avatar answered Sep 27 '22 20:09

Jonathan


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); } 
like image 41
Peter Lawrey Avatar answered Sep 27 '22 20:09

Peter Lawrey