先上源码:
/**
* Returns a fixed-size list backed by the specified array. (Changes to
* the returned list "write through" to the array.) This method acts
* as bridge between array-based and collection-based APIs, in
* combination with {@link Collection#toArray}. The returned list is
* serializable and implements {@link RandomAccess}.
*
* <p>This method also provides a convenient way to create a fixed-size
* list initialized to contain several elements:
* <pre>
* List<String> stooges = Arrays.asList("Larry", "Moe", "Curly");
* </pre>
*
* @param <T> the class of the objects in the array
* @param a the array by which the list will be backed
* @return a list view of the specified array
*/
@SafeVarargs
@SuppressWarnings("varargs")
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
最近的项目中有个地方需要将当前数组转换成list,并判断里面是否包含某个数:
private boolean containsColor(int[] colors, int color) {
// 1. Erroe: return Arrays.asList(colors).contains(color);
/* 2. Right:
for (int paletteColor : colors) {
if (paletteColor == color) {
return true;
}
}
return false;*/
// 3. Right
Integer[] integers = Arrays.stream(colors).boxed().toArray(Integer[]::new);
List arrayList = Arrays.asList(integers);
return Arrays.asList(arrayList).contains(color);
}
最初使用方法一:
结果一直是 false,debug后发现 Arrays.asList() 生成的 List size为1,
list.get(0)结果为color数组;
知道原因所在,改为二,成功;
想追跟究底,继续尝试 + 百度,找到了方法三,成功;
其中发现 size 一直是1,原因在于在Arrays.asList中,接受一个变长参数,一般可看做数组参数,但是因为int[] 本身就是一个类型,所以colors作为参数传递时,编译器认为只传了一个变量,这个变量的类型是int数组,所以size为1。基本类型是不能作为泛型的参数,按道理应该使用包装类型,但这里却没有报错,因为数组是可以泛型化的,所以转换后在list中就有一个类型为int的数组,所以该方法体现的适配器模式,只是转换接口,后台的数据还是那个数组,这也很好的解释了
(一)为什么该方法将数组与列表链接起来,当更新其中之一时,另一个自动更新。
(二)该方法目前对基本类型(byte,short,int,long,float,double,boolean)的支持并不太好。
另外使用该方法还需要注意:
(三)该方法生成的list长度固定,所以不支持影响list长度的操作(add,remove等),支持一些修改操作(set等)。
所以 Arrays.asList 方法适合已有数组数据或者一些元素,而需要快速构建一个List,只用于读取操作,而不用于添加或者删除数据。
如果是想将一个数组转化成一个列表并做增加删除操作的话,可以使用:
List<WaiterLevel> levelList = new ArrayList<WaiterLevel>(Arrays.asList("a", "b", "c"));