码迷,mamicode.com
首页 > 其他好文 > 详细

ArrayList源码分析

时间:2018-07-16 18:29:03      阅读:161      评论:0      收藏:0      [点我收藏+]

标签:ati   int   length   array   指定位置   oid   ret   aci   定位   

1、成员变量

private static final int DEFAULT_CAPACITY = 10;

private static final Object[] EMPTY_ELEMENTDATA = {};

transient Object[] elementData;

private int size;

/**
 * 有初始化容量的构造参数
 */
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);
    }
}

/**
 * 构造一个空数组,使用默认容量10
 */
public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

2、get()方法

public E get(int index) {
    rangeCheck(index);

    return elementData(index);
}

// 检查数组下标是否越界
private void rangeCheck(int index) {
    if (index >= size)
        throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}

E elementData(int index) {
    // 根据索引直接返回数组中的元素
    return (E) elementData[index];
}

3、set()方法

public E set(int index, E element) {
    rangeCheck(index); // 检查数组下标是否越界

    E oldValue = elementData(index);
    elementData[index] = element;
    return oldValue;
}

4、add()方法

/**
 * 在数组末尾插入元素
 */
public boolean add(E e) {
    ensureCapacityInternal(size + 1);
    elementData[size++] = e;
    return true;
}

/**
 * 在指定位置插入元素
 */
public void add(int index, E element) {
    rangeCheckForAdd(index);

    ensureCapacityInternal(size + 1);  // Increments modCount!!
    
    // 将数组中的元素从index开始,全部向后移动一个位置
    System.arraycopy(elementData, index, elementData, index + 1,
                     size - index);
    elementData[index] = element;
    size++;
}

/**
 * 处理数组容量与扩容
 */
private void ensureCapacityInternal(int minCapacity) {

    // 判断是不是默认空数组
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); // 设置容量
    }

    ensureExplicitCapacity(minCapacity);
}

private void ensureExplicitCapacity(int minCapacity) {
    modCount++;

    // 判断容量是否大于实际的数组长度
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}

private void grow(int minCapacity) {
    int oldCapacity = elementData.length; // 老容量
    int newCapacity = oldCapacity + (oldCapacity >> 1); // 新容量 = 老容量 + 老容量的一半
    if (newCapacity - minCapacity < 0)
        // 初始化时newCapacity=0
        newCapacity = minCapacity;
    if (newCapacity - MAX_ARRAY_SIZE > 0) // 扩容后超过了最大数组容量
    
        // 实际数组的长度+1 > MAX_ARRAY_SIZE 返回Integer.MAX_VALUE否则返回MAX_ARRAY_SIZE
        newCapacity = hugeCapacity(minCapacity); // 最大是Integer.MAX_VALUE
    
    // 复制数组,对多只能复制前Integer.MAX_VALUE个
    elementData = Arrays.copyOf(elementData, newCapacity);
}

未完,待续...

ArrayList源码分析

标签:ati   int   length   array   指定位置   oid   ret   aci   定位   

原文地址:https://www.cnblogs.com/liycode/p/9319095.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!