I have seen the question: Create ArrayList from array
However when I try that solution with following code, it doesn't quite work in all the cases:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
public class ToArrayList {
public static void main(String[] args) {
// this works
String[] elements = new String[] { "Ryan", "Julie", "Bob" };
List<String> list = new ArrayList<String>(Arrays.asList(elements));
System.out.println(list);
// this works
List<Integer> intList = null;
intList = Arrays.asList(3, 5);
System.out.println(intList);
int[] intArray = new int[] { 0, 1 };
// this doesn't work!
intList = new ArrayList<Integer>(Arrays.asList(intArray));
System.out.println(intList);
}
}
What am I doing wrong here? Shouldn't the code intList = new ArrayList<Integer>(Arrays.asList(intArray));
compile just fine?
The problem in
intList = new ArrayList<Integer>(Arrays.asList(intArray));
is that int[]
is considered as a single Object
instance since a primitive array extends from Object
. This would work if you have Integer[]
instead of int[]
since now you're sending an array of Object
.
Integer[] intArray = new Integer[] { 0, 1 };
//now you're sending a Object array
intList = new ArrayList<Integer>(Arrays.asList(intArray));
From your comment: if you want to still use an int[]
(or another primitive type array) as main data, then you need to create an additional array with the wrapper class. For this example:
int[] intArray = new int[] { 0, 1 };
Integer[] integerArray = new Integer[intArray.length];
int i = 0;
for(int intValue : intArray) {
integerArray[i++] = intValue;
}
intList = new ArrayList<Integer>(Arrays.asList(integerArray));
But since you're already using a for
loop, I wouldn't mind using a temp wrapper class array, just add your items directly into the list:
int[] intArray = new int[] { 0, 1 };
intList = new ArrayList<Integer>();
for(int intValue : intArray) {
intList.add(intValue);
}
With Java 8 you can do it in one line:
int[] intArr = { 1, 1, 2, 3, 5, 8, 11};
List<Integer> list = Arrays.stream(intArr).boxed().collect(Collectors.toList());
list.forEach(System.out::println);
It doesn't work because you're using an int[]
instead of Integer[]
. Try this:
Integer[] intArray = new Integer[] { 0, 1 };
// this should work now
intList = new ArrayList<Integer>(Arrays.asList(intArray));
The issue is about Autoboxing. Java automatically converts int
to Integer
automatically, but it does not convert int[]
to Integer[]
. Hence the reason.
public static <T> List<T> asList(T... a)
asList
is defined as above. It expects a vararg of type T
. i.e. it can take an array of objects of type T
. In your case because Java cannot convert int[]
to Integer[]
, hence it takes type T
as int[]
rather than Integer
as desired. Hence you get a list of type List<int[]
. You will have to manually convert it into `Integer[]
from int[]
There is an excellent item in the book Effective Java
by Joshua Bloch where he explains the pits with varargs and this is one of them.
Collection wants Objects and primitives don't derive from Object. so Integer
allow but int
is not allow.
So you have to use wrapper class Integer
instead of int
which is primitive type.
Just example:
Integer[] intArray = new Integer[] { 0, 1 };
intList = new ArrayList<Integer>(Arrays.asList(intArray));