简述
我们在开发过程中使用Arrays.asList()的原因无非是想将数组或一些元素转为集合,但有时候得到的集合并不一定是我们想要的那个集合。
我们在使用的时候,需要注意什么呢?
一、不能将基本数据类型做为Arrays.asList方法的参数
public class TestArraysAsList {
public static void main(String[] args) {
int data [] = {1,2,3,4,5};
List list= Arrays.asList(data);
System.out.println("列表中的元素数量是:"+list.size());
}
}
运行结果:
1
显然不是我们想要的结果,我们来看一下Arrays.asList的方法说明:输入一个变长参数,返回一个固定长度的列表。看源码:
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
方法的入参是一个泛型变长参数,我们知道基本类型是不能泛型化的,也就是说8个基本类型不能作为泛型参数,要想作为泛型参数就必须使用其所对应的包装类型。所以说知道了原因,改起来也比较简单,将 int
替换成Integer
就可以了。
二、Arrays.asList方法产生的List的对象不可更改
public class TestArraysAsList {
public static void main(String[] args) {
Integer data [] = {1,2,3,4,5};
List list= Arrays.asList(data);
list.add(6);
System.out.println("列表中的元素数量是:"+list.size());
}
}
运行结果:
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.add(AbstractList.java:148)
at java.util.AbstractList.add(AbstractList.java:108)
at object.ArrayAsListTest.main(ArrayAsListTest.java:11)
咦?报错了,UnsupportedOperationException
不支持的操作,不支持add
吗?看源码:
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
// 从上面可以得知,直接new了一个ArrayList对象返回,再看下这个类,这个ArrayList是否跟我们常用的java.util.ArrayList不一样?
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);
}
@Override
public int size() {
return a.length;
}
// ……
}
这个ArrayList是一个静态私有内部类,除了Arrays能访问外,其它类都不能访问,这个类确实没有提供add()
方法,那既然可以调用,应该就是父类AbstractList
提供了,顺便看一眼:
public boolean add(E e) {
add(size(), e);
return true;
}
public void add(int index, E element) {
throw new UnsupportedOperationException();
}
父类提供了,但是没有实现,直接抛出了一个异常,需要子类覆盖这个方法实现,但是ArrayList没有覆盖,所以不支持增加操作。
顺便看了下ArrayList支持的方法有:size()
、toArray()
、get()
、set()
、contains()
、indexOf()
、spliterator()
、sort()
三、原数组发生变化,使用ArrayList得到的list会同步变化
public class TestArraysAsList {
public static void main(String[] args) {
Integer data [] = {1,2,3,4,5};
data[0] = 0;
List list= Arrays.asList(data);
System.out.println("数组data[0]:"+data[0]);
System.out.println("list(0):"+list.get(0));
}
}
运行结果:
数组data[0]:0
list(0):0
结果是一样的,为啥呢?看源码:
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
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);
}
}
Arrays.ArrayList
将外部数组的引用直接通过“=”赋予内部的泛型数组,所以本质指向同一个数组。所以说如果真有这样的场景,还需要将转化过来的list
,重新new ArrayList(list);
一下就可以了。
有任何问题欢迎微信搜索【Hugh的白板】私信我,一起探讨,一起学习