java源码_ArrayList(二)

接上文分析ArrayList核心方法
1.作为动态数组,扩容方法至关重要

a.确保最低容量的公共方法

public void ensureCapacity(int minCapacity) {
    int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
        // any size if not default element table
        ? 0
        // larger than default for default empty table. It's already
        // supposed to be at default size.
        : DEFAULT_CAPACITY;

    if (minCapacity > minExpand) {
        ensureExplicitCapacity(minCapacity);
    }
}

b.内部的确保容量方法

private void ensureCapacityInternal(int minCapacity) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
    }

    ensureExplicitCapacity(minCapacity);
}

c.实际的确保容量方法,modCount++,

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

    // overflow-conscious code
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}

d.增加容量的方法

d1.普通方法

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)
        newCapacity = hugeCapacity(minCapacity);
    // minCapacity is usually close to size, so this is a win:
    elementData = Arrays.copyOf(elementData, newCapacity);
}

d2.大容量

private static int hugeCapacity(int minCapacity) {
    if (minCapacity < 0) // overflow
        throw new OutOfMemoryError();
    return (minCapacity > MAX_ARRAY_SIZE) ?
        Integer.MAX_VALUE :
        MAX_ARRAY_SIZE;
}

2.依次看增删改查方法,增删改都是结构性修改

a. add

public boolean add(E e) {
    ensureCapacityInternal(size + 1);  // Increments modCount!!//为了增加modCount
    elementData[size++] = e;
    return true;
}
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++;
}

b.remove

public E remove(int index) {
    rangeCheck(index);//检查index合法性

    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//最后一个元素设为null,同时减小size


    return oldValue;
}
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
}

c.set

public E set(int index, E element) {
    rangeCheck(index);//检测index合法性

    E oldValue = elementData(index);//取出现在的值
    elementData[index] = element;//直接修改数组
    return oldValue;
}
E elementData(int index) {
    return (E) elementData[index];
}

d.get

public E get(int index) {
    rangeCheck(index);
//检测index合法性
return elementData(index) ;//直接取值}

e.contains,index,lastIndex

public boolean contains(Object o) {
    return indexOf(o) >= 0;//通过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;
}
public int lastIndexOf(Object o) {//倒序遍历数组
    if (o == null) {
        for (int i = size-1; i >= 0; i--)
            if (elementData[i]==null)
                return i;
    } else {
        for (int i = size-1; i >= 0; i--)
            if (o.equals(elementData[i]))
                return i;
    }
    return -1;
}

f.clear

public void clear() {
    modCount++;

    // clear to let GC do its work
    for (int i = 0; i < size; i++)
        elementData[i] = null;

    size = 0;
}

发布了138 篇原创文章 · 获赞 10 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/idealemail/article/details/80350922