问:下面程序的输出是什么?为什么?
public class Demo {
public static void main(String[] args) {
int[] data = {1, 2, 3, 4};
List list = Arrays.asList(data);
System.out.println(list.size());
}
}
答:打印结果为:1。首先我们看下 asList 方法的实现源码,如下:
public static <T> List<T> asList (T ...a ){
return new ArrayList<>(a);
}
可以看到返回的 Arrays 的内部类 ArrayList 构造方法接收的是一个类型为 T 的数组,而基本类型是不能作为泛型参数的,所以这里参数 a 只能接收引用类型,自然为了编译通过编译器就把上面的 int[] 数组当做了一个引用参数,所以 size 为 1,要想修改这个问题很简单,将 int[] 换成 Integer[] 即可。所以原始类型不能作为 Arrays.asList 方法的参数,否则会被当做一个参数。
问:下面程序能正常运行吗?为什么?
public class Demo {
public static void main(String[] args) {
Integer[] data = {1, 2, 3, 4};
List<Integer> list = Arrays.asList(data);
list.add(5);
}
}
答:上面程序运行抛出 UnsupportedOperationException
异常。理论上正常的 ArrayList 都是支持 add 方法的,这里为什么会不支持呢?因为 Arrays.asList 返回的 ArrayList 是 Arrays 的静态内部私有类实现,不是常用的那个 ArrayList,这里的 ArrayList 继承自 AbstractList,但是只实现了 size、toArray、get、set、contains 几个方法,其他常见的 add、remove 等方法都没实现,所以才抛出异常了。此外像 ArrayList<Integer> list = Arrays.asList(1, 2, 3);
这样的代码是无法编译通过的,因为 list 已经不是常用的 ArrayList 了,Arrays 内部的 ArrayList 是私有的。所以说 Arrays.asList 返回的 List 是一个不可变长度的列表,此列表不再具备原 List 的很多特性,因此慎用 Arrays.asList 方法。
问:下面程序的输出结果是什么?
ArrayList<String> list = new ArrayList<>();
list.add("android");
Vector<String> vector = new Vector<>();
vector.add("android");
System.out.println(list.equals(vector));
答:上面程序运行结果为 true。因为集合列表的相等只关心元素数据的比较,其 equals 方法都是 AbstractList 中实现的,比较的依据是通过迭代器遍历元素挨个 equals 比较,所以自然为 true,其他集合 Map、Set 同理。