数组转换成List一般使用Arrays.asList,但是转换后的List只能查询、更改,不能增加和删除。还有其他几种方式转换,这里记录几种转换的差异。
常用方式 通过 Arrays.asList(strArray) 方式将数组转换List后,不能对List增删,只能查询和修改,否则抛出异常。
1 List list = Arrays.asList(strArray)
增加操作 1 2 3 4 5 6 7 private void testArrayCastToListError () { String[] strArray = new String [2 ]; List list = Arrays.asList(strArray); list.add("1" ); System.out.println(list); }
异常 1 2 3 4 5 Exception in thread "main" java.lang.UnsupportedOperationException at java.util.AbstractList.add(AbstractList.java:148 ) at java.util.AbstractList.add(AbstractList.java:108 ) at com.darwin.junit.Calculator.testArrayCastToList(Calculator.java:19 ) at com.darwin.junit.Calculator.main(Calculator.java:44 )
异常原因 Arrays.asList(strArray)返回值是java.util.Arrays类中一个私有静态内部类java.util.Arrays.ArrayList,它并非java.util.ArrayList类。java.util.Arrays.ArrayList类具有 set(),get(),contains()等方法,但是不具有添加add()或删除remove()方法,所以调用add()方法会报错。
转换返回值类型 Arrays.asList(strArray)返回值是java.util.Arrays类中一个私有静态内部类java.util.Arrays.ArrayList,那么通过java.util.ArrayList的构造器,将Arrays.asList(strArray)的返回值由java.util.Arrays.ArrayList转为java.util.ArrayList,java.util.ArrayList可以对List进行增删改查。
1 ArrayList<String> list = new ArrayList <String>(Arrays.asList(strArray))
增加 1 2 3 4 5 6 private void testArrayCastToListRight () { String[] strArray = new String [2 ]; ArrayList<String> list = new ArrayList <String>(Arrays.asList(strArray)) ; list.add("1" ); System.out.println(list); }
结果
工具类转换 Collections.addAll(arrayList, strArray)转换,首先创建一个空List,再将数组元素放进去,这种方式大多数情况下是最快的。
Adds all of the specified elements to the specified collection. Elements to be added may be specified individually or as an array. The behavior of this convenience method is identical to that of c.addAll(Arrays.asList(elements)), but this method is likely to run significantly faster under most implementations.
1 2 ArrayList< String> arrayList = new ArrayList <String>(strArray.length); Collections.addAll(arrayList, strArray);
增加 1 2 3 4 5 6 7 8 private void testArrayCastToListEfficient () { String[] strArray = new String [2 ]; ArrayList< String> arrayList = new ArrayList <String>(strArray.length); Collections.addAll(arrayList, strArray); arrayList.add("1" ); System.out.println(arrayList); } [null , null , 1 ]
易错点 数据类型 1 2 int [] intArray1 = new int [2 ];List<Integer> list1 = Arrays.asList(intArray1);
报错原因:等号两边类型不一致,当然编译不通过。
原因:只能用Integer[]转List<Integer>,即只能用基本数据类型的包装类型,才能直接转为List。
List源码: 1 public interface List <E> extends Collection <E> {}
Arrays.asList()源码 1 2 3 public static <T> List<T> asList (T... a) { return new ArrayList <>(a); }
从上述源码中可以看出,List声明时,需要传递一个泛型<E>作为形参,asList()参数类型也是泛型中的通配类型<T>。Java中所有的泛型必须是引用类型。
其他8种基本数据类型byte、short、int、long、float、double、char也都不是引用类型,所以8种基本数据类型都不能作为List的形参。但String、数组、class、interface是引用类型,都可以作为List的形参,所以存在List<Runnable>接口类型的集合、List<int[]>数组类型的集合、List<String>类的集合。但不存在list<byte>、list<short> 等基本类型的集合。