使用Arrays.asList注意事项
来源:互联网 发布:淘宝售假申诉补充留言 编辑:程序博客网 时间:2024/05/18 13:31
Arrays.asList()
方法将数组转成list,是java.util.Arrays类的静态方法。能够很方便地将数组转为List.该方法和Collection
接口的toArray()
方法,组成了基于数组与基于Collection的API之间互相转化的桥梁.
用一小段代码做个实验:
public static void main(String[] args) { int[] a = {1, 2, 3, 4, 5}; Integer[] b = {1, 2, 3, 4, 5}; String[] c = {"a", "b", "c"}; System.out.println(Arrays.asList(a)); System.out.println(Arrays.asList(b)); System.out.println(Arrays.asList(c)); List<String> list = Arrays.asList(c); list.add("d"); System.out.println(list);}
这段代码看起来不会有任何问题,但是实际呢?
看下输出的结果
[[I@7217fef][1, 2, 3, 4, 5][a, b, c]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.zhuhengwei.ArraysTest.main(ArraysTest.java:22)Process finished with exit code 1
奇怪的地方有两点:
- int[] a没有正确地转化想要的list
- list.add(“d”)抛出了
UnsupportedOperationException
异常
下面通过源码解释下出现的情况
问题1:int[] a没有正确转为list
首先看下方法声明
public static <T> List<T> asList(T... a) { return new ArrayList<>(a);}
乍一看,很正常,没什么问题.
分析1:
asList(T…a)方法参数是一个泛型可变参数,而泛型的类型参数只能是类类型(包括自定义类),不能是基本数据类型.将int[] a基本类型的数组传入时,解释器将整个数组作为了可变参数的一个元素.
所以此时a ={int[1][]@…},是一个二维数组,所以转换后的list中只有一个元素,且元素是一个数组.基本类型是不能泛型化的,要想作为泛型参数就必须使用对应的包装类型。
问题2: 方法返回的是ArrayList,调用add()
为什么会报出异常呢?
分析2: 此ArrayList非彼ArrayList,它是Arrays中的静态私有内部类.
private static class ArrayList<E> extends AbstractList<E> implements RandomAccess, java.io.Serializable{ private final E[] a; ArrayList(E[] array) { if (array==null) throw new NullPointerException(); a = array; }}
该内部类ArrayList没有覆写add,remove等方法,这些方法由AbstractList提供.而且数组E[]为final类型.
public E set(int index, E element) { throw new UnsupportedOperationException();}public void add(int index, E element) { throw new UnsupportedOperationException();}public E remove(int index) { throw new UnsupportedOperationException();}
这些方法均抛出UnsupportedOperationException
异常,所以问题就在于此.
在Arrays.asList方法上的doc上清楚地写着:该方法返回固定大小的list.而且E[]为final,所以是只读的.
Returns a fixed-size list backed by the specified array.
原因在于内部类只继承了AbstractList,而没有覆写add,remove等能够改变list容量的方法.在AbstractList类上方的doc中也有说明.
To implement an unmodifiable list, the programmer needs only to extend
this class and provide implementations for the {@link #get(int)} and
{@link List#size() size()} methods.
To implement a modifiable list, the programmer must additionally
override the {@link #set(int, Object) set(int, E)} method (which otherwise
throws an {@code UnsupportedOperationException}). If the list is
variable-size the programmer must additionally override the
{@link #add(int, Object) add(int, E)} and {@link #remove(int)} methods.
实现一个不可变list,只需要继承AbstractList,提供get()
和size()
方法;要实现可修改list,必须覆写set()
;要实现动态增删元素的list,必须覆写add()
等方法.
而我们经常用到的ArrayList正是这样做的,自己实现了add,romove等方法.
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable{...}
那么如何解决UnsupportedOperationException
的问题呢?转为常用的java.util.ArrayList
.
List<String> list = new ArrayList<String>(Arrays.asList(c));
结论
- 基本类型不能作为泛型参数传入.如果需要,改成对应的包装类
- Arrays.asList返回的是固定只读的ArrayList,如果后面可能会改变,慎用该方法.
- 使用Arrays.asList注意事项
- Arrays.asList使用注意事项
- Java Arrays.asList注意事项
- 关于Arrays.asList(T... a)方法的使用注意事项
- Arrays的asList方法注意事项
- Arrays.asList 使用注意
- Arrays.asList()方法使用
- Arrays.asList使用
- Arrays.asList使用注意
- 谨慎使用Arrays.asList()
- Arrays.asList使用
- Arrays.asList()方法使用
- Arrays.asList使用注意
- Arrays.asList的使用
- java中Arrays.asList(T... a)注意事项
- Arrays.asList()方法的使用
- Arrays.asList()方法的使用
- Arrays类—Arrays.asList()方法使用
- Android 友盟统计
- HTML基础(一)
- RecyclerView和listview的区别
- JavaScript 箭头函数
- intellij IDEA+scala编译报错
- 使用Arrays.asList注意事项
- C语言数独游戏求解
- LSTM理解
- CODE[VS]1015 计算器的改良
- Android 音视频开发(四):使用 Camera API 采集视频数据
- vue+mint ui+省市区三级联动(编辑地址)
- Java数组实现栈
- ceph scrub errors
- Android的安全机制