Java ArrayList部分源码研究
2018-01-12 22:17
239 查看
/* 今天晚上看了会ArrayList源码,研究了一下主要的函数。主要有以下几个函数: add() remove() ensureCapacity() grow() hugeCapacity() fastremove() (和remove稍有区别) 以及内部类Itr 实现了Iterator接口 基本分析写在注释里了。 */ public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable { public ArrayList(int initialCapacity) { // 如果指定大小,则new一个指定大小的数组 // 否则elementData为一个Oject类型的空数组(Oject[] EMPTY_ELEMENTDATA = {}) if (initialCapacity > 0) { this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { this.elementData = EMPTY_ELEMENTDATA; } else { throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); } } public ArrayList() { // 不传入任何参数,默认为空数组 // Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {} this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; } // 通常size < elementData.length // 去掉数组多余部分以减少需要存储的空间 public void trimToSize() { modCount++; if (size < elementData.length) { elementData = (size == 0) ? EMPTY_ELEMENTDATA : Arrays.copyOf(elementData, size); } } public void ensureCapacity(int minCapacity) { // 不是默认空数组则为0,否则为10 int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) // any size if not default element table ? 0 // larger than default for default empty table. It's already // supposed to be at default size. : DEFAULT_CAPACITY; // 如果传入参数大于minExpand,则增加容量,否则不增加 if (minCapacity > minExpand) { ensureExplicitCapacity(minCapacity); } } private void ensureExplicitCapacity(int minCapacity) { modCount++; // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity); } private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1); // 默认新容量是旧容量的1.5倍 if (newCapacity - minCapacity < 0) // 如果新容量还是满足不了指定容量 newCapacity = minCapacity; // 则取所要需求的容量 if (newCapacity - MAX_ARRAY_SIZE > 0) // 如果超过数组最大长度 // hugeCapacity中,如果minCapacity为负数,表明整型溢出,抛出OOM // 大于MAX_ARRAY_SIZE则取Integer.MAX_VALUE否则取MAX_ARRAY_SIZE // 当 newCapcity = (oldCapacity + (oldCapacity >> 1)) > MAX_ARRAY_SIZE // && minCapacity < 0 时发生 newCapacity = hugeCapacity(minCapacity); // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); } public boolean add(E e) { // 默认往后添加元素 ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; } public void add(int index, E element) { // 在指定下表增加元素 // 越界检查 rangeCheckForAdd(index); // 确保有size+1的容量,ensureCapacityInternal会调用ensureExplicitCapacity ensureCapacityInternal(size + 1); // Increments modCount!! // 将原数组index下标开始的元素复制到从index+1开始,也就是往后移,空出index下标位置 System.arraycopy(elementData, index, elementData, index + 1, size - index); elementData[index] = element; size++; } public E remove(int index) { rangeCheck(index); modCount++; E oldValue = elementData(index); // 旧值 int numMoved = size - index - 1; if (numMoved > 0) // 将index位置之后的元素往前移动 System.arraycopy(elementData, index+1, elementData, index, numMoved); // 原本的最后一个设置成空,jvm会回收该空间 elementData[--size] = null; // clear to let GC do its work // 返回旧值 return oldValue; } public boolean remove(Object o) { // 区分空和不空,需要一次循环 // == 和 equals if (o == null) { for (int index = 0; index < size; index++) if (elementData[index] == null) { fastRemove(index); return true; } } else { for (int index = 0; index < size; index++) if (o.equals(elementData[index])) { fastRemove(index); return true; } } return false; } private void fastRemove(int index) { // 和remove不同的地方就是不反回旧值且不进行越界检查 modCount++; 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 work } // 内部类Itr实现了Iterator接口 private class Itr implements Iterator<E> { int cursor; // 迭代器中,指向当前元素的游标 int lastRet = -1; // 最后一次返回元素的下标,初始为-1 int expectedModCount = modCount; // 修改次数 public boolean hasNext() { return cursor != size; } @SuppressWarnings("unchecked") public E next() { // 如果在使用迭代器的过程中,用了ArrayList的修改操作,则会导致迭代器失效 // 因为ArrayList的add,remove操作会使得modCount++,使得modCount!=expectedModCount checkForComodification(); int i = cursor; if (i >= size) throw new NoSuchElementException(); Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) throw new ConcurrentModificationException(); cursor = i + 1; return (E) elementData[lastRet = i]; } public void remove() { // 在第一次使用next后才能进行remove if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { ArrayList.this.remove(lastRet); cursor = lastRet; lastRet = -1; expectedModCount = modCount; // 使用迭代器的remove不会造成迭代器失效 } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } } }
相关文章推荐
- Java容器深入研究(jdk 1.8)--- ArrayList总结与源码分析
- Java 集合系列03之 ArrayList详细介绍(源码解析)和使用示例
- java.util.ArrayList 实例推动源码分析
- 第一篇:JAVA集合之ArrayList源码剖析
- 【Java部分源码分析之io篇】6.InputStreamReader
- Java ArrayList源码小结
- java中List接口的实现类 ArrayList,LinkedList,Vector 的区别 list实现类源码分析
- Java 集合系列03之 ArrayList详细介绍(源码解析)和使用示例
- 【Java深入】ArrayList源码剖析(二)
- Java 源码分析之ArrayList
- Java ArrayList 源码分析
- Java从入门到放弃(五)集合框架之ArrayList源码(1)
- 【Java深入研究】3、HashMap源码解析
- 初探Java源码之ArrayList
- 从源码理解ArrayList.java
- java.util.ArrayList 源码
- Java集合:ArrayList使用详解及源码分析
- java ArrayList 源码解析(jdk1.6)
- Java1.8集合源码:ArrayList 详细解析
- Java源码阅读之ArrayList(4)