浅谈Arrays.asList()

浅谈Arrays.asList()

1.什么Arrays.asList()?

asList()Arrays类中一个静态方法,主要作用是:将数组转换为list,也就是数组和集合连接在一起。

2.关于其使用的几个注意事项:

​ 使用该方法时会有几大“坑”,同学们一定要注意。

2.1 不支持集合的addremove方法

​ 使用工具类Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方法,它的add/remove/clear方法会抛出UnsupportOperationException异常。

​ 因为从源码分析,asList的返回对象是一个Arrays的内部类ArrayList,并没有实现集合的修改方法。

​ 源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Arrays {
//...
public static <T> List<T> asList(T... a) {
return new Arrays.ArrayList(a);
}

private static class ArrayList<E> extends AbstractList<E> implements RandomAccess, Serializable {
//...
ArrayList(E[] array) {
this.a = (Object[])Objects.requireNonNull(array)
}
//...
}
//...
}

​ 因此,在使用其方法时,必须确保其长度不再改变。

2.2 该方法不适用于基本数据类型数组

​ 先给大家做个演示:

1
2
3
4
5
6
7
8
public class AsListDemo {
public static void main(String[] args) {
int[] nums = {1, 2, 3};
List list = Arrays.asList(nums);
System.out.println("list's size = " + list.size());
//结果:list's size = 1
}
}

​ 我们发现和我们想的并不一样,我们认为list的大小应该为3,现在却是1。这是因为,在Arrays.asList中,该方法接受一个变长参数,一般可看做数组参数,但是因为int[]本身就是一个类型,所以nums变量作为参数传递时,编译器认为只传了一个变量,这个变量的类型是int[],所以size为1。

​ 基本类型是不能作为泛型的参数,按道理应该使用包装类型,但这里缺没有报错,因为数组是可以泛型化的,所以转换后在list中就有一个类型为int的数组。

2.3 该方法连接起来的数组和集合,只要修改其中一个,另一个也被修改。

​ 注意:仅仅针对对象数组类型,基本数据类型数组不具备该特性

1
2
3
4
5
6
7
8
9
10
11
public class AsListDemo {
public static void main(String[] args) {
String[] str = {"Hello", "i'm", "Djt"};
List<String> slist = Arrays.asList(str);
System.out.println("str[2] = " + str[2]);
// 结果 : str[2] = Djt
slist.set(2, "djt");
System.out.println("str[2] = " + str[2]);
// 结果 : str[2] = djt
}
}

​ 我们发现对slist进行修改,str中也发生了修改。Arrays.asList体现的是适配器模式,只是转换接口,后台的数据仍是数组。sliststr都是引用,他们指向的是同一个数组,指向同一个存储空间。

如果要使用真正的ArrayList,用 ArrayList 的构造器可以将其转变成真正的 ArrayList。