一、java.util.Arrays.asList() 的一般用法
如果将一个数组转换为 List,可以将需要转化的数组作为参数,或者直接把数组元素作为参数。但是其中参数必须是包装类类型,如果使用的是基本数据类型,可以使用Jdk8新特性进行解决
具体代码如下:
//1将需要转化的数组作为参数
String[] arrayList = {"1","2","3"};
List<String> myList = Arrays.asList(arrayList);
//2.直接把数组元素作为参数
List<String> myList = Arrays.asList("1","2","3");
对于参数类型的不同的使用和解决方案如下:
//1.使用包装类数组
Integer[] arrayList = {1,2,3};
List<Integer> lists = arrays.asList(arrayList);
sout(lists.size());//3
lists.foreach(system.out::print);//1,2,3
//2.使用基本类型数组
int[] arr = {1,2,3};
List lists = arrays.asList(arr);
sout(lists.size());//1
lists.foreach(system.out::print);//其打印出来的结果是是对象的hashCode
以上打印出来的结果,并不是我们所预期的结果
asList 方法的参数必须是对象或者对象数组,而原生数据类型不是对象——这也正是包装类出现的一个主要原因。当传入一个原生数据类型数组时,asList 的真正得到的参数就不是数组中的元素,而是数组对象本身!此时List 的唯一元素就是这个数组。
因为asList方法的签名如下:
public static <T> List<T> asList(T... a)
参数类型是 T ,根据官方文档的描述,T 是数组元素的 class
我们知道任何类型的对象都有一个 class 属性,这个属性代表了这个类型本身。原生数据类型,比如 int,short,long等,是没有这个属性的,具有 class 属性的是它们所对应的包装类 Integer,Short,Long。
//可使用jdk8新特性进行解决
//Java 8 新引入的 Stream 操作
List myList = Arrays.stream(arr).boxed().collect(Collectors.toList());//1,2,3
对于arrays.asList()返回一个由指定数组生成的固定大小的 List。不可对其返回的值进行随意的增加和删除操作。
@SafeVarargs
@SuppressWarnings("varargs")
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
//方法中的的确确生成了一个 ArrayList ,这不应该是支持动态扩容的吗?别着急,接着往下看。紧跟在 asList 方法后面,有这样一个内部类:
private static class ArrayList<E> extends AbstractList<E> implements RandomAccess, java.io.Serializable
{
private static final long serialVersionUID = -2764017481108945198L;
private final E[] a;
ArrayList(E[] array) {
a = Objects.requireNonNull(array);
}
@Override
public int size() {
return a.length;
}
//...
}
这个内部类也叫 ArrayList ,更重要的是在这个内部类中有一个被声明为 final 的数组 a ,所有传入的元素都会被保存在这个数组 a 中。到此,谜底又揭晓了: asList 方法返回的确实是一个 ArrayList ,但这个 ArrayList 并不是 java.util.ArrayList ,而是 java.util.Arrays 的一个内部类。这个内部类用一个 final 数组来保存元素,因此用 asList 方法产生的 ArrayList 是不可修改大小的。