Java集合(3)--ArrayList源码分析

默认初始容量为10,底层用的是对象数组实现的。

public void ensureCapacity(int minCapacity)。确保数组最小容量,用于添加元素的时候。

它的父类AbstractList只有一个抽象方法abstract public E get(int index);

modCount:记录list结构被改变的次数,其实是改变大小时会自增,主要是add和remove,set并不会使modCount自增。

会影响modCount的操作:add,remove、ensureCapacityInternal、fastRemove、clear、trimToSize、removeRange(是那些会改变容量的操作)。

还有个listIterator()方法,返回一个迭代器。

扩容的时候的代码:

 

public void ensureCapacity(int minCapacity) {
        if (minCapacity > 0)
            ensureCapacityInternal(minCapacity);
}

private void ensureCapacityInternal(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;
//变成原来容量的1.5倍
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); } private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow throw new OutOfMemoryError(); return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; }

再看一个方法:

 

public void trimToSize() {  
     modCount++;  
     int oldCapacity = elementData.length;  
     if (size < oldCapacity) {  
             elementData = Arrays.copyOf(elementData, size);  
     }  
}

 

elementData的长度会被拓展,size标记的是其中包含的元素的个数。所以会出现size很小但elementData.length很大的情况,将出现空间的浪费。trimToSize将返回一个新的数组给elementData,元素内容保持不变length跟size相同,节省空间

 

private void fastRemove(int index)不进行边界检查,不返回删除的值。

clear方法:没有修改elementData长度,只是将所有元素置为nullsize设置为0。

 

subList会调用父类(ArrayList)的removeRange方法

 

    原文作者:山野豪杰
    原文地址: http://www.cnblogs.com/pipi-style/p/ArrayList_source.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞