Java数组转集合?肯定想到使用Arrays.asList(),注意雷区,小心踩雷。
1.雷区一
- 先来看一个程序示例:
int[] arr = {1,2,3,4,5};
List list = Arrays.asList(arr);
System.out.println(list.size());
System.out.println(list);
// list.size() = 1
- 结果:
- 按理说得到到List.size()的大小应该为5,但是程序输出结果为1,所以这就是第一个雷区,看看Arrays.asList的源码:
//.....以上源码信息已省略
@SafeVarargs
@SuppressWarnings("varargs")
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
//.....以下源码信息已省略
- Arrays.asList源码:传入一个变长泛型参数(注意泛型!),返回一个List集合,在Java中,泛型要求包容的是对象类型,而基本数据类型在Java中不属于对象,但是在示例代码中传入一个int[]类型的数组,程序并没有报错,是因为int[]是一个数组对象,示例代码把int类型的数组作为泛型传入,所以代码没有报错。
- 所以使用Arrays.asList时,如果传入数组类型为基本数据类型,就使用对应的包装类作为入参:
Integer[] arr = {1,2,3,4,5};
List list = Arrays.asList(arr);
System.out.println("list.size() = "+list.size());
System.out.println(list);
- 结果:
2.雷区二
- 代码示例:
Integer[] arr = {1,2,3,4,5};
List list = Arrays.asList(arr);
System.out.println("list.size = "+ list.size());
list.add(6);
System.out.println("add -> list.size = "+ list.size());
- 结果:
- java.lang.UnsupportedOperationException,List集合进行add()操作竟然报错,同样看源码:
/**
* @serial include
*/
private static class ArrayList<E> extends AbstractList<E>
implements RandomAccess, java.io.Serializable
{
private static final long serialVersionUID = -2764017481108945198L;
private final E[] a;
ArrayList(E[] array) {
a = Objects.requireNonNull(array);
}
//.....以下源码信息已省略
- 从源码可以看到这个ArrayList是一私有静态内部类,这个类中并没有提供add()和remove()方法,但是在它继承的AbstractList父类中提供了add()和remove()方法,只是没有提供具体的逻辑实现:
// 父类AbstractList
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
public boolean add(E e) {
add(size(), e);
return true;
}
public E remove(int index) {
throw new UnsupportedOperationException();
}
}
- 也就是需要继承的子类自己去覆写父类中的add()和remove()方法,但是Arrays类中并没有去进行覆写,所以使用Arrays.asList返回的是一个长度不可变的列表,其集合长度取决于入参数组的长度,返回的列表不支持新增和删除操作。
- 如果需要对Arrays.asList返回的list集合进行增删操作的话,就需要将Arrays.asList返回的list转换成 new ArrayList:
Integer[] arr = {1,2,3,4,5};
List list = Arrays.asList(arr);
List arrayList = new ArrayList<>(list);
System.out.println("list.size = "+ arrayList.size());
arrayList.add(6);
System.out.println("add -> list.size = "+ arrayList.size());
- 结果:
- 最后这里比较一下Arrays下的ArrayList 和 常用的ArrayList: