ArrayList源码解析

原文链接
ArrayList底层使用数组实现,所以随机访问特定位置的元素的速度特别快,时间复杂度为0(1)

transient Object[] elementData; // non-private to simplify nested class access

ArrayList默认分配大小为10的容量

/**
 * Default initial capacity.
 */
private static final int DEFAULT_CAPACITY = 10;

ArrayList可以给定特定索引删除元素,时间复杂度为O(n)

/**
 * Removes the element at the specified position in this list.
 * Shifts any subsequent elements to the left (subtracts one from their
 * indices).
 *
 * @param index the index of the element to be removed
 * @return the element that was removed from the list
 * @throws IndexOutOfBoundsException {@inheritDoc}
 */
public E remove(int index) {
    //检查元素索引的正确性
    rangeCheck(index);

    //当ArrayList被修改时,该变量累加
    modCount++;
    //获取对应索引位置的元素
    E oldValue = elementData(index);

    //计算需要往前移动的元素个数
    int numMoved = size - index - 1;

    //如果删除的不是最后一个元素,则把对应index后面的元素依次往前移动一个位置
    if (numMoved > 0)
        System.arraycopy(elementData, index+1, elementData, index,
                         numMoved);
    //移动完成后需要吧数组中的最后一个元素置为空,方便GC回收
    elementData[--size] = null; // clear to let GC do its work

    return oldValue;
}

也可以删除ArrayList中对应的对象,时间复杂度也为O(n)

/**
 * Removes the first occurrence of the specified element from this list,
 * if it is present.  If the list does not contain the element, it is
 * unchanged.  More formally, removes the element with the lowest index
 * <tt>i</tt> such that
 * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>
 * (if such an element exists).  Returns <tt>true</tt> if this list
 * contained the specified element (or equivalently, if this list
 * changed as a result of the call).
 *
 * @param o element to be removed from this list, if present
 * @return <tt>true</tt> if this list contained the specified element
 */
public boolean remove(Object o) {
    //可以看出ArrayList可以存储null值,先判断是否删除null,否则如果当执行equals方法时会抛出空指针异常
    if (o == null) {
        for (int index = 0; index < size; index++)
            //暴力循环获取第一个为null的索引
            if (elementData[index] == null) {
                //快速移除元素,没有进行索引判断,因为该索引是安全的,不会越界
                fastRemove(index);
                //删除成功
                return true;
            }
    } else {
        for (int index = 0; index < size; index++)
            //调用equals方法暴力查找需要移除的元素
            if (o.equals(elementData[index])) {
                fastRemove(index);
                return true;
            }
    }
    return false;
}

fastRemove方法如下,该方法删除元素时跳过了索引检查

/*
 * Private remove method that skips bounds checking and does not
 * return the value removed.
 */
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
}

接下来看看add方法

/**
 * Appends the specified element to the end of this list.
 *
 * @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;
}

在指定位置添加元素,时间复杂度为O(n)

/**
 * 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).
 *
 * @param index index at which the specified element is to be inserted
 * @param element element to be inserted
 * @throws IndexOutOfBoundsException {@inheritDoc}
 */
public void add(int index, E element) {
    //首先检查index的合法性(0<=index<=arrayList.size)
    rangeCheckForAdd(index);

    //扩容处理
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    //指定位置的所有元素依次往后移动一个位置
    System.arraycopy(elementData, index, elementData, index + 1,
                     size - index);
    //插入元素
    elementData[index] = element;
    size++;
}

清空ArrayList,时间复杂度O(n)

/**
 * Removes all of the elements from this list.  The list will
 * be empty after this call returns.
 */
public void clear() {
    //每次修改该变量都会自加操作
    modCount++;

    // clear to let GC do its work
    for (int i = 0; i < size; i++)
        //全部置空,让GC清理内存
        elementData[i] = null;

    //长度变为0
    size = 0;
}

判断是否含某一个元素

public boolean contains(Object o) {
    //获取对应索引进行判断
    return indexOf(o) >= 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值