Arrays.asList的实现
2016-07-01 00:00
169 查看
今天看Java编程思想看到容器这块的时候,发现说了Arrays.asList方法的一些特别之处,所以写篇博文来记录一下。
Arrays是一个数组的工具类,用于操作数组。
public static <T> List<T> Arrays.asList(T... a) 这是asList的方法定义。意思就是传入类型为T的数组或者多个T类型的变量参数,就会返回一个List<T>的对象。
Java编程思想上是这么说的:"你可以使用Arrays.asList方法的输出作为List使用,但是其底层表示的是数组,因此不能调整尺寸,如果你试图用add和delete方法在列表中添加和删除元素就有可能会引发去修改数组的尺寸尝试,因此,你将会在运行时获得Unsupported Operation异常"。
那么,首先我来来通过简单的测试来看看这句话的正确性:
父类AbstractList中的add方法实现
以此可见在AbstractList中是不支持add的实现的。
Arrays是一个数组的工具类,用于操作数组。
public static <T> List<T> Arrays.asList(T... a) 这是asList的方法定义。意思就是传入类型为T的数组或者多个T类型的变量参数,就会返回一个List<T>的对象。
Java编程思想上是这么说的:"你可以使用Arrays.asList方法的输出作为List使用,但是其底层表示的是数组,因此不能调整尺寸,如果你试图用add和delete方法在列表中添加和删除元素就有可能会引发去修改数组的尺寸尝试,因此,你将会在运行时获得Unsupported Operation异常"。
那么,首先我来来通过简单的测试来看看这句话的正确性:
[code=plain] public class ArraysTest { public static void main(String[] args){ List<Integer> aList = Arrays.asList(1,2); for(int i : aList){ System.out.println(i); } aList.add(3); } }
[code=plain]看一下运行的结果:
[code=plain]1 2 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.zhu.util.ArraysTest.main(ArraysTest.java:17) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
好吧,果不其然。异常抛出! 接下来,我们看看源码,为什么会出现这种情况
[code=language-java]@SafeVarargs public static <T> List<T> asList(T... a) { return new ArrayList<>(a); } /** * @serial include */ 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) { if (array==null) throw new NullPointerException(); a = array; } public int size() { return a.length; } public Object[] toArray() { return a.clone(); } public <T> T[] toArray(T[] a) { int size = size(); if (a.length < size) return Arrays.copyOf(this.a, size, (Class<? extends T[]>) a.getClass()); System.arraycopy(this.a, 0, a, 0, size); if (a.length > size) a[size] = null; return a; } public E get(int index) { return a[index]; } public E set(int index, E element) { E oldValue = a[index]; a[index] = element; return oldValue; } public int indexOf(Object o) { if (o==null) { for (int i=0; i<a.length; i++) if (a[i]==null) return i; } else { for (int i=0; i<a.length; i++) if (o.equals(a[i])) return i; } return -1; } public boolean contains(Object o) { return indexOf(o) != -1; } }
Arrays.asList返回的是本身静态内部类ArrayList,而不是我们经常使用的java.util.ArrayList。看看这内部类的实现,直接是将构造器传进来的数组直接作为存储数据的基础。而add和delete方法是用的是父类AbstractList的实现。
父类AbstractList中的add方法实现
[code=language-java]public boolean add(E e) { add(size(), e); return true; } public void add(int index, E element) { throw new UnsupportedOperationException(); }
以此可见在AbstractList中是不支持add的实现的。
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树