总结
利用Arrays.asList方法返回的List是不允许add和remove的,这种list的长度不可变,因为底层依然是写数组。
Arrays.asList的返回值是调用是传入T类型的List,所以传入啥,返回啥的列表
T... a 底层本来就是转换为T[] x的数组,所以如果传入的T是数组,最后的底层参数是二维数组T[][] y.
Arrays.asList(T... a)方法的作用
将数组转为集合的方法,返回的是List集合。和Collection的toArray对应,是数组和集合间相互转换的两个桥梁方法。asList接受的参数是T... a,这是一种可变参数的表示,这种可变参数底层其实会转化为T[] x的形式,所以可以接受多个T类型的传参。
Arrays.asList的示例代码
下面写了一段利用Arrays的asList方法将数组转为List链表的测试方法:
import java.util.*;/*** Created by lili on 15/11/13.*/
public classTest {public static voidmain(String[] args) {
List integers = Arrays.asList(1, 2, 3, 4);int[] arr = new int[]{1,2,3,4};
List list0 =Arrays.asList(arr);
System.out.println(list0);//list0.add(new int[]{111});//出错 for(int[] a : list0){
System.out.println("mark1: "+a);//打印的是地址,Integer数组
for(inti : a){
System.out.println(i);
}
}
System.out.println("----------------------");//list0.set(0,11);//java.lang.ArrayStoreException: java.lang.Integer
list0.set(0, new int[]{11});
List list1 = Arrays.asList(1,2,3,4);
System.out.println(list1);for(inta : list1){
System.out.println(a);
}
System.out.println("-----------------------");
list1.set(0, 11);//list1.add(11);//不支持add
for(inta : list1){
System.out.println(a);
}
}
}
上述代码首先明显的说明了一个问题:
利用Arrays.asList方法返回的List是不允许add的,同时测试了remove也不可以,但是可以改为各个索引位置的值。隐含表示List长度不可变。
反编译出来的结果是:
//
//Source code recreated from a .class file by IntelliJ IDEA//(powered by Fernflower decompiler)//
importjava.util.Arrays;importjava.util.Iterator;importjava.util.List;public classTest {publicTest() {
}public static voidmain(String[] var0) {
List var1= Arrays.asList(new Integer[]{Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3), Integer.valueOf(4)});int[] var2 = new int[]{1, 2, 3, 4};
List var3= Arrays.asList(new int[][]{var2});
System.out.println(var3);
Iterator var4=var3.iterator();while(var4.hasNext()) {int[] var5 = (int[])var4.next();
System.out.println("mark1: " +var5);int[] var6 =var5;int var7 =var5.length;for(int var8 = 0; var8 < var7; ++var8) {int var9 =var6[var8];
System.out.println(var9);
}
}
System.out.println("----------------------");
var3.set(0, new int[]{11});
List var10= Arrays.asList(new Integer[]{Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3), Integer.valueOf(4)});
System.out.println(var10);
Iterator var11=var10.iterator();intvar12;while(var11.hasNext()) {
var12=((Integer)var11.next()).intValue();
System.out.println(var12);
}
System.out.println("-----------------------");
var10.set(0, Integer.valueOf(11));
var11=var10.iterator();while(var11.hasNext()) {
var12=((Integer)var11.next()).intValue();
System.out.println(var12);
}
}
}
上述反编译出来的结果除了表明增强型for循环会转变为Iterator外,更重要的是表明asList接受的传参最后会转变为数组:
如果直接在asList(int a,int b,int c,int d)中传入一个个的值,最后转换的是int[]{a,b,c,d},是一维数组。
如果传入的本来是一个数组asList(int[] arr),最后转换成一个二维数组,且该二维数组只有一个一维数组对象。
最终输出结果:
[[I@27077aa7]
mark1: [I@27077aa71
2
3
4
----------------------[1, 2, 3, 4]1
2
3
4
-----------------------
11
2
3
4Process finished with exit code0
Arrays.asList的方法结构
在这里我们最大的疑惑是为啥返回的是List,却不允许添加元素呢?下面看看asList的源码:
/*** 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 {@linkCollection#toArray}. The returned list is
* serializable and implements {@linkRandomAccess}.
*
*
This method also provides a convenient way to create a fixed-size
* list initialized to contain several elements:
*
* List<String> stooges = Arrays.asList("Larry", "Moe", "Curly");
*
*
*@parama the array by which the list will be backed
*@returna list view of the specified array*/@SafeVarargspublic static ListasList(T... a) {return new ArrayList<>(a);
}
asList是一个泛型方法,可以接受可变参数传递,而返回值是调用方法时传入类型T的List,所以这里返回值是什么类型是一个重要的问题,在使用时要注意区分。
之所以不能修改,注释的解释是:返回一个受指定数组支持的固定大小的列表。(对返回列表的更改会“直接写”到数组。)-->由于数组长度不可变,所以不可增删