jdk1.8中arrayList源码解析
程序员文章站
2022-06-04 19:20:49
...
-
先来看不指定数组长度时采用new 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. **方法说明如下** * 存储ArrayList元素在数组缓冲区。 * ArrayList的容量是此数组缓冲区的长度。 * 任何空ArrayList 即对应类中已经定义的常量DEFAULTCAPACITY_EMPTY_ELEMENTDATA * 在添加第一个元素时扩展为DEFAULT_CAPACITY。//10
* Constructs an empty list with an initial capacity of ten.
* 构造一个空列表的初始容量为10
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
2. 再来看一下创建对象即指定长度的情况:
* Constructs an empty list with the specified initial capacity.
*
* @param initialCapacity the initial capacity of the list
* @throws IllegalArgumentException if the specified initial capacity
* is negative
*/
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);
}
}
3. 当向集合添加元素的时候,调用add方法,比如list.add(num,”a”)
* Inserts the specified element at the specified position in this
* list. Shifts the element currently at that position (if any) and
* any subsequent elements to the right (adds one to their indices).
*
* 在指定的位置插入指定的元素
* 将目前位于该位置的元素(如果有)
* 和所有随后的元素(在其原索引加一)。
将原来的list复制到新的list中,修改长度size
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++;
}
-
向list中添加元素但不指定下标
* Appends the specified element to the end of this list. * 在结尾加元素,当出现超出10时 * @param e element to be appended to this list * @return <tt>true</tt> (as specified by {@link Collection#add}) public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; }
调用了
private void ensureCapacityInternal(int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);//max用来取大 } ensureExplicitCapacity(minCapacity); }
然后又调用了
private void ensureExplicitCapacity(int minCapacity) { modCount++; // overflow-conscious code 越界-意识 代码(越界10了) 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) // 当长度过大 --private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; // @Native public static final int MAX_VALUE = 0x7fffffff; newCapacity = hugeCapacity(minCapacity); // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); } private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow//太长抛异常 内存溢出 throw new OutOfMemoryError(); return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; }