java collection与数组(Array)互转
先确定几个概念,这里说的数组元素,除基本类型数组外,并非指元素对象本身,而是它们的引用。换句话说,基本数组的元素是数值本身,非基本数组的元素都是一个地址(对应指针)。
1.collection的元素不能是基本类型
首先,各种collectioin容器的元素都只能是继承了Object类的对象,所以不能是8种基本类型。如果要放入基本类型,必需要用它们对应的包装器进行包装。
关于基本类型与包装类的区别:基本类型是储存在堆栈中的,这一点和C++的非new基本类型一样(c++所有非new对象都是在堆栈中的),也和C#的值类型一样;包装类是储存在栈中的,和c++中new出来的对象以及C#中的引用类型一样;
在调用Arrays的静态方法asList(<T>[])时,T是根据collection声明时的泛型参数确定的,所以不仅collection的泛型参数不能是基本类型,传入的数组也不能是基本类型,如下面这样,编译时就会报错:
1 import java.util.*; 2 public class TestArray2List{ 3 4 public static void main(String[] args){ 5 inte[] valueTypeArray={2,3,4,5,6}; 6 List<Integer> valueTypeList=new ArrayList<Integer>(); 7 valueTypeList.addAll(Arrays.asList(valueTypeArray)); 8 System.out.println("valueTypeList:\n"); 9 for(int value:valueTypeList){ 10 System.out.println(value); 11 12 } 13 14 } 15 16 }
错误信息:
.\TestArray2List.java:7: 错误: 对于addAll(List<int[]>), 找不到合适的方法 valueTypeList.addAll(Arrays.asList(valueTypeArray)); ^ 方法 Collection.addAll(Collection<? extends Integer>)不适用 (参数不匹配; 推断类型不符合上限 推断: int[] 上限: Integer,Object) 方法 List.addAll(Collection<? extends Integer>)不适用 (参数不匹配; 推断类型不符合上限 推断: int[] 上限: Integer,Object)
2.Arrays.asList()是对数组元素(复制指针)的复制
再次强调,非基本类型数组元素只是一个指针。因为collection的类型只能是非基本类型,所以collectioin存的都是指针。当用Arrays.asList(),把一个Array转为一个List<T>时,是把所有的指针复制一遍,比如下面的,更改原数组的值(指针指向一个新对向)时,List<T>的值不变,所以再次都是输出1:
import java.util.*; public class TestArray2List{ public static void main(String[] args){ Integer[] valueTypeArray={1,2,3,4,5,6}; List<Integer> valueTypeList=new ArrayList<Integer>(); valueTypeList.addAll(Arrays.asList(valueTypeArray)); System.out.println("valueTypeList[0]:"); System.out.println(valueTypeList.get(0)); valueTypeArray[0]=new Integer(99); System.out.println(valueTypeList.get(0)); } }
输出:
1 1
3.Arrays.asList()具体的对象值不会复制
上面已经提到了,asList()是对指针的复制,List<T>和Array是两个指针序列,对应的元素指向相同的对象,比如下面这样,Array的每个元素是一个指向int数组的二级指针,List<T>的每个元素也是二级指针,它们对应的元素指向同一个int[](一个int数据序列)。因为指向同一个对象,所以对象的内容发生变化时,List<T>和原Array都会变化。
import java.util.*; public class TestArray2List{ public static void main(String[] args){ int[][] valueTypeArray={{1,2},{3,4},{5,6}}; List<int[]> valueTypeList=new ArrayList<int[]>(); valueTypeList.addAll(Arrays.asList(valueTypeArray)); System.out.println("valueTypeList[0]:"); System.out.println(valueTypeList.get(0)[0]); valueTypeArray[0][0]=99; System.out.println(valueTypeList.get(0)[0]); } }
输出:
1 99