ArrayList源码阅读 - jdk11

ArrayList 实现的list接口,list接口,list接口继承了collction接口。Arraylist是顺序容器,可以放入null,有capacity容量,当容量不足时,会自动增大底层容量,数据是Object[]

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

因为是数组实现,插入数据的O(n),获取操作O(1)

自动扩容,对于大于元素长度 && (不为空并且大于最小容量),进行扩容,modCount是作用于iterator,当该值异常改变是抛出ConcurrentModificationException

public void ensureCapacity(int minCapacity) {
    if (minCapacity > elementData.length
        && !(elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
             && minCapacity <= DEFAULT_CAPACITY)) {
    modCount++;
    grow(minCapacity);
}
}

// grow 调用copyOf,新建并复制一份
  private Object[] grow(int minCapacity) {
        return elementData = Arrays.copyOf(elementData,
                                           newCapacity(minCapacity));
    }

add(),将指定的元素追加到列表末尾.
add方法调用时,list对象的size == 存储对象的长度就会进行扩容最大长度+1

//  基本类型返回,不用判空?
public boolean add(E e) {
        modCount++;
        add(e, elementData, size);
        return true;
    }

// 这里调用的add是个比较有意思的方法,这个方法是为了报错字节码小于35和C1编译器循环调用才拆出来的
// 这里实际是方法内联,将两个方法的字节码整合成一个方法。
/**
     * This helper method split out from add(E) to keep method
     * bytecode size under 35 (the -XX:MaxInlineSize default value),
     * which helps when add(E) is called in a C1-compiled loop.
     */
    private void add(E e, Object[] elementData, int s) {
        if (s == elementData.length)
            elementData = grow();
        elementData[s] = e;
        size = s + 1;
    }

   private Object[] grow() {
        return grow(size + 1);
    }

// 复制
    public void add(int index, E element) {
        rangeCheckForAdd(index);
        modCount++;
        final int s;
        Object[] elementData;
        if ((s = size) == (elementData = this.elementData).length)
            elementData = grow();
        System.arraycopy(elementData, index,
                         elementData, index + 1,
                         s - index);
        elementData[index] = element;
        size = s + 1;
    }

addAll()基本相同不做赘述

set,返回当前位置原值
remove ,返回当前位置原址
trimToSize,调整list长度为当前元素长度大小

public E set(int index, E element) {
    Objects.checkIndex(index, size);
    E oldValue = elementData(index);
    elementData[index] = element;
    return oldValue;
}

 public E remove(int index) {
        Objects.checkIndex(index, size);
        final Object[] es = elementData;

        @SuppressWarnings("unchecked") E oldValue = (E) es[index];
        fastRemove(es, index);

        return oldValue;
}
// 原位置置为空
   private void fastRemove(Object[] es, int i) {
        modCount++;
        final int newSize;
        if ((newSize = size - 1) > i)
            System.arraycopy(es, i + 1, es, i, newSize - i);
        es[size = newSize] = null;
    }
// 遍历找到index
  public boolean remove(Object o) {
        final Object[] es = elementData;
        final int size = this.size;
        int i = 0;
        found: {
            if (o == null) {
                for (; i < size; i++)
                    if (es[i] == null)
                        break found;
            } else {
                for (; i < size; i++)
                    if (o.equals(es[i]))
                        break found;
            }
            return false;
        }
        fastRemove(es, i);
        return true;
    }

// 空返回空 ,不为空返回元素大小
 public void trimToSize() {
        modCount++;
        if (size < elementData.length) {
            elementData = (size == 0)
              ? EMPTY_ELEMENTDATA
              : Arrays.copyOf(elementData, size);
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值