List源码学习之ArrayList

  ArrayList 内部结构为一个可重复的对象数组(可存空对象)。

内部有以下几个参数:

/**
* 默认初始容量
*/
private static final int DEFAULT_CAPACITY = 10;

/**
* 用于空实例的共享空数组实例
*/
private static final Object[] EMPTY_ELEMENTDATA = {};

/**
* 存储数组列表元素的数组缓冲区。数组列表的容量是这个数组缓冲区的长度
*/
private transient Object[] elementData;

/**
* 数组列表的大小
*
* @serial
*/
private int size;

//默认数组最大值
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

分析几个内部方法:

1.indexOf(Object o):

public int indexOf(Object o) {
    if (o == null) {
        for (int i = 0; i < size; i++)
            if (elementData[i]==null)
                return i;
    } else {
        for (int i = 0; i < size; i++)
            if (o.equals(elementData[i]))
                return i;
    }
    return -1;
}

循环对象数组进行比较,返回第一个匹配到的对象的下标,若未匹配到返回-1,提供给contains(Object o) 方法。

2.add(Object o): 添加前需要对容量进行容量检查 扩展容量。

public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // 确保内部容量:
        elementData[size++] = e; //添加元素
        return true;
    }

//确保内部容量
private void ensureCapacityInternal(int minCapacity) {
        if (elementData == 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;
     //扩展容量为之前容量的3/2  int newCapacity = oldCapacity + (oldCapacity >> 1); if (newCapacity - minCapacity < 0) newCapacity = minCapacity;
     //如果扩展后的容量大于数组最大值,扩展至最大容量 if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); // elementData = Arrays.copyOf(elementData, newCapacity); } private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow throw new OutOfMemoryError();
    如果最小容量大于数组最大值,则扩展至Integer的最大值否则扩展至数组默认最大值 return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; }

3.remove(int index):按数组下标移除对象元素,

public E remove(int index) {
    //边界检查 rangeCheck(index);      //修改次数+1 modCount
++; E oldValue = elementData(index); 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 return oldValue; }

4.remove(Object o):按对象移除,只移除匹配到的第一个相同对象

public boolean remove(Object o) {
//从前往后匹配,若匹配到则根据下标进行删除。
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) { 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 }

5.addAll(Collection<? extends E> c):将指定集合中的所有元素追加到数组的末尾

public boolean addAll(Collection<? extends E> c) {
        Object[] a = c.toArray();
        int numNew = a.length;
     //扩容 ensureCapacityInternal(size
+ numNew); // Increments modCount
     //数组拷贝 System.arraycopy(a, 0, elementData, size, numNew); size += numNew; return numNew != 0; }

6.addAll(int index, Collection<? extends E> c):从数组的某个位置添加指定集合

public boolean addAll(int index, Collection<? extends E> c) {
        rangeCheckForAdd(index);
    
     //将集合转化为对象数组 Object[] a
= c.toArray(); int numNew = a.length;
     //扩容 ensureCapacityInternal(size
+ numNew); // Increments modCount      //将原数组index之后的数据拷贝至index+numNew之后 int numMoved = size - index; if (numMoved > 0) System.arraycopy(elementData, index, elementData, index + numNew, numMoved);      //将指定数组添加至原数组 System.arraycopy(a, 0, elementData, index, numNew); size += numNew; return numNew != 0; }

进阶之路从此开始,路在脚下早已铺好,走与不走全看你想不想欣赏沿途的风景———————AmbitiousMice

原文地址:https://www.cnblogs.com/AmbitiousMice/p/8044522.html