Arrays.asList()的用途
Arrays作为一个操作数组的工具类,提供了将数组转化为List的操作方法:asList(),从而实现对List的操作方式来操作元素。
@SafeVarargs
@SuppressWarnings("varargs")
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
UnsupportedOperationException
asList()方法的返回值是一个ArrayList,但是在使用add()、remove()方法时则会抛出UnsupportedOperationException异常,为什么返回的ArrayList不支持动态扩容和删除?
public class SampleDemo {
public static void main(String[] args) {
List<String> stringList = Arrays.asList("aa", "bb", "cc");
stringList.add("aa");
stringList.remove(1);
}
}
Exception in thread "main" java.lang.UnsupportedOperationException
at java.base/java.util.AbstractList.remove(AbstractList.java:167)
at com.example.demo.SampleDemo.main(SampleDemo.java:10)
在点开asList()源码后可以看到对该方法的注释:
Returns a fixed-size list backed by the specified array.
Changes made to the array will be visible in the returned list, and changes made to the list will be visible in the array.
The returned list is Serializable and implements RandomAccess.
The returned list implements the optional Collection methods, except those that would change the size of the returned list.
Those methods leave the list unchanged and throw UnsupportedOperationException.
-
可以看到asList()方法返回一个入参数组长度的特定List对象,且对于原数组的元素的操作在List中是可见的,通过操作List中的元素在原数组中也是可见的。返回的List对象实现了部分的Collection集合方法,但其中会改变数组长度的方法则会抛出UnsupportedOperationException异常。
-
因为入参使用了泛型参数数组Class形式,因此对原数组和List进行元素修改等操作因为对象引用的关系都是相互可见的。
Integer[] integers = new Integer[]{1, 2, 3};
List<Integer> integerList = Arrays.asList(integers);
System.out.println(integerList);
integers[2] = 5;
System.out.println(integerList);
integerList.set(2,6);
System.out.println(Arrays.toString(integers));
[1, 2, 3]
[1, 2, 5]
[1, 2, 6]
- 同时通过返回值跳转,可以看到所返回的ArrayList对象是Arrays内部自定义继承AbstractList的子类,但其没有对add()、remove()等特定方法的实现,因此需要查看父类AbstractList源码的相关实现
// asList()返回值
return new ArrayList<>(a);
// 内部类ArrayList
private static class ArrayList<E> extends AbstractList<E> implements RandomAccess, java.io.Serializable{}
// AbstractList方法源码
public void add(int index, E element) {
throw new UnsupportedOperationException();
}
public E remove(int index) {
throw new UnsupportedOperationException();
}
由此可知,因为ArrayList类没有对父类的方法进行自己的具体实现的重写,所以默认会抛出UnsupportedOperationException。
如何解决
若想要进行相关的操作,返回的List对象需要重新进行包装:
List<String> pets = new ArrayList<String>(Arrays.asList("aa","bb"));