arraylist源码解读

上传人:正** 文档编号:42121772 上传时间:2018-06-01 格式:DOCX 页数:7 大小:23.51KB
返回 下载 相关 举报
arraylist源码解读_第1页
第1页 / 共7页
arraylist源码解读_第2页
第2页 / 共7页
arraylist源码解读_第3页
第3页 / 共7页
arraylist源码解读_第4页
第4页 / 共7页
arraylist源码解读_第5页
第5页 / 共7页
点击查看更多>>
资源描述

《arraylist源码解读》由会员分享,可在线阅读,更多相关《arraylist源码解读(7页珍藏版)》请在金锄头文库上搜索。

1、public class ArrayList extends AbstractListimplements List, RandomAccess, Cloneable, java.io.Serializable支持泛型,父类父类AbstractList:抽象类,List 接口, RandomAccess: Marker interface used by List implementations to indicate that they support fast (generally constant time) random access.标志快速随机存取 Cloneable:cloneS

2、erializable:序列化成员变量成员变量private static final long serialVersionUID = 8683452581122892189L; 序列化的版本号,需要 序列化的都要有。 private static final int DEFAULT_CAPACITY = 10; 默认的容量大小是 10private static final Object EMPTY_ELEMENTDATA = ; 空实例private static final Object DEFAULTCAPACITY_EMPTY_ELEMENTDATA = ; EMPTY_ELEMEN

3、TDATA 与 DEFAULTCAPACITY_EMPTY_ELEMENTDATA 的区别在于,当添加完 第一个元素的时候,后者知道要扩充多少。 transient Object elementData; 这个是非常重要的成员变量,也就是把元素存储在这个 Object 类型的数组里,transient 表示这个变量不进行序列化。private int size; 就是 ArrayList 的元素的数量。构造函数构造函数public ArrayList(int initialCapacity) if (initialCapacity 0) this.elementData = new Objec

4、tinitialCapacity; else if (initialCapacity = 0) this.elementData = EMPTY_ELEMENTDATA; else throw new IllegalArgumentException(“Illegal Capacity: “+initialCapacity);第一个构造函数,传入了初始容量,如果大于 0,生成一个新对象,大小为初始容量 的,如果是等于 0,初始一个空的对象,否则抛异常。public ArrayList() this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;

5、第二个构造一个空的 arrayList,初始容量为 10public ArrayList(Collection c) elementData = c.toArray();if (size = elementData.length) != 0) / c.toArray might (incorrectly) not return Object (see 6260652)if (elementData.getClass() != Object.class)elementData = Arrays.copyOf(elementData, size, Object.class); else / rep

6、lace with empty array.this.elementData = EMPTY_ELEMENTDATA;第三个构造函数,传入一个集合,先转换为一个数组,然后看长度是否为 0,如果为 0 的话就初始化空的一个对象,如果不为 0 并且不为 Object 类型的数组,就转换成 O bject 类型的。重要的成员函数public boolean add(E e) ensureCapacityInternal(size + 1); / Increments modCount!elementDatasize+ = e;return true;这个函数是添加一个元素,首先判断容量是否够,如果够

7、在数组的末尾添加新的元素, 返回成功,接下来看最重要的部分,是怎么扩展容量的,打开上面的 ensureCapacityInternal 函数。private void ensureCapacityInternal(int minCapacity) if (elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA) minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);ensureExplicitCapacity(minCapacity);private void ensureExplicitCapaci

8、ty(int minCapacity) modCount+;/ overflow-conscious codeif (minCapacity - elementData.length 0)grow(minCapacity);看上面的代码,可以知道,当要求的最小容量比现在数组的长度大的时候,就会调用 grow()函数来动态增加容量。其中有一个变量可能会比较疑惑,就是 modCount,这是干什么 的,它是 AbstractList 下的一个变量,用来记录 list 的大小变化的次数的,这个变量有什么 用呢,当进行数组循环遍历的时候,会在遍历前记住临时的 modeCount,遍历结束后, modC

9、ount 与之前的记录进行比较,如果不相等的话就抛 ConcurrentModificationException 这个异常。因为是线程不安全的,遍历的时候,如果数组的数据的元素的数量有变化会出 异常。private void grow(int minCapacity) / overflow-conscious codeint oldCapacity = elementData.length;int newCapacity = oldCapacity + (oldCapacity 1);if (newCapacity - minCapacity 0)newCapacity = hugeCapa

10、city(minCapacity);/ minCapacity is usually close to size, so this is a win:elementData = Arrays.copyOf(elementData, newCapacity);接下来认真的看 grow 这个函数,新扩充的容量是原来容量的 1.5 倍,如果还是不够, 那么新的容量就直接为所需要的最小容量,最后进行数组的扩充。public void add(int index, E element) rangeCheckForAdd(index);ensureCapacityInternal(size + 1); /

11、 Increments modCount!System.arraycopy(elementData, index, elementData, index + 1,size - index);elementDataindex = element;size+;这个函数是在某个位置添加一个元素,首先 index 会不会超出索引,超出抛异常,调 用前面分析过的容量保证的函数,其实数组在某个位置添加元素挺蛋疼的,需要把这个位 置及后面的元素都往后移一位,调用 System.arraycopy,把元素复制过去,然后空出来的那 个位置插入元素。public E remove(int index) range

12、Check(index);modCount+;E oldValue = elementData(index);int numMoved = size - index - 1;if (numMoved 0)System.arraycopy(elementData, index+1, elementData, index,numMoved);elementData-size = null; / clear to let GC do its workreturn oldValue;上面是删除的函数,先判断是否超出索引位置,然后 int numMoved = size-index-1;是什 么意思呢,

13、就是删除了某个位置的元素,对于数组来说,得把之后的元素都给往前移一个 位置的,所以得把需要移动元素的个数给算出来。所以说数组结构,增删真是蛋疼啊。public boolean remove(Object o) if (o = null) for (int index = 0; index = size)throw new NoSuchElementException();Object elementData = ArrayList.this.elementData;if (i = elementData.length)throw new ConcurrentModificationExcept

14、ion();cursor = i + 1;return (E) elementDatalastRet = i;返回下一个元素的函数,checkForComodification,它的作用上面说的 modCount 分析过了, 如果 cursor 的索引大于或者等于 size,抛 NoSuchElementException 异常,肯定没有这个元 素,如果是 cursor= elementData.length 就代表的是在这期间数组的长度变小了,有其它线 程操作的原因,抛异常 ConcurrentModificationException()。如果都没问题,cursor 加 1,然 后返回元素

15、,并且 lastRet 标记。public void remove() if (lastRet consumer) Objects.requireNonNull(consumer);final int size = ArrayList.this.size;int i = cursor;if (i = size) return;final Object elementData = ArrayList.this.elementData;if (i = elementData.length) throw new ConcurrentModificationException();while (i !

16、= size / update once at end of iteration to reduce heap write trafficcursor = i;lastRet = i - 1;checkForComodification();这个函数是 java8 才有的,也就是 iterator 对 lamda 表达式的支持,就是一个遍历而已。OverrideSuppressWarnings(“unchecked“)public void sort(Comparator c) final int expectedModCount = modCount;Arrays.sort(E) elementData, 0, size, c);if (modCount != expectedModCount) throw new Concurrent

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 中学教育 > 其它中学文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号