ArrayList源码 (基于1.7)
前言
推荐一位大牛的博客: https://blog.csdn.net/eson_15/article/details/51121833
我基本都是看的他的源码分析,刚开始如果直接看jdk源码可能有一些晕,难免会中途放弃,建议先根据博客,根据别人分析好的一步一步走,会有恍然大悟的感觉,然后再自己去根据jdk对照着看,最后脱离博客在看一遍。
正文
- ArrayList简介。
- ArrayList是可以动态增长和缩减的索引序列,它是基于数组实现的List类。
- ArrayList源码分析。
- 属性。
/**
默认的数组长度,调用默认的构造方法时,会分配此常量
* Default initial capacity. */ private static final int DEFAULT_CAPACITY = 10; /**
空数组对象
* Shared empty array instance used for empty instances. */ private static final Object[] EMPTY_ELEMENTDATA = {}; /**
空数组对象
* Shared empty array instance used for default sized empty instances. We * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when * first element is added. */ private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; /**
元素数组,实际ArrayList的元素就是存放在他这里的。(指定为不可被序列化)
* The array buffer into which the elements of the ArrayList are stored. * The capacity of the ArrayList is the length of this array buffer. Any * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA * will be expanded to DEFAULT_CAPACITY when the first element is added. */ transient Object[] elementData; // non-private to simplify nested class access /**
数组元素个数
* The size of the ArrayList (the number of elements it contains). * * @serial */ private int size;
- 属性。
-
- 构造方法。
// 默认的构造方法,给数组设置成空数组 public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; } // 提供一个集合作为参数。会把集合中的所有元素复制到数组中 public ArrayList(Collection<? extends E> 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 { // replace with empty array. this.elementData = EMPTY_ELEMENTDATA; } } // 提供一个参数,可指定数组的长度 public ArrayList(int initialCapacity) { if (initialCapacity > 0) { this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { this.elementData = EMPTY_ELEMENTDATA; } else { throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); } }
- 常用方法。
//*** 添加元素(在数组的尾部添加) *** // 1 先判断是否可以插入到数组(不够会扩容数组) // 2 插入元素到数组 // 3 返回true public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; } // 判断数组 // 1 如果目前为空数组,给数组分配默认长度 // 2 交给这位兄弟处理:ensureExplicitCapacity方法 private void ensureCapacityInternal(int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); } ensureExplicitCapacity(minCapacity); } // 判断目前数组是否需要扩容 // 1 modCount是对数组 修改的 记录数,每次增或删都会自增 // 2 判断数组长度是否足够(是否需要扩容) // 3 如果需要,交给下一个兄弟:grow方法 private void ensureExplicitCapacity(int minCapacity) { modCount++; // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity); } // 扩容过程 // 1 将现在的数组长度oldCapacity 扩容1.5倍 // 2 如果扩容后的长度newCapacity还小,那就取 minCapacity(理论上不可能) // 3 如果扩容后的长度newCapacity超过最大长度,调用hugeCapacity方法处理一下。(取最大长度) // 4 开始扩容,废弃老数组,生成新数组,赋值给elementData private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1); if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); } //*** 添加元素(在数组的任意位置添加) *** // 1 判断index是否合法 // 2 判断数组是否需要扩容 // 3 处理数组(指定位置后面的数组后移) // 4 添加元素到指定的位置 public void add(int index, E element) { rangeCheckForAdd(index); ensureCapacityInternal(size + 1); // Increments modCount!! System.arraycopy(elementData, index, elementData, index + 1, size - index); elementData[index] = element; size++; }
- 构造方法。
后面的有时间在分析~~以上个人见解,如有错误之处还望指出!
关于http协议