ArrayList源码

ArrayList源码

一:ArrayList底层结构

ArrayList底层结构是基于数组实现的。

二:ArrayList源码

2.1:默认构造方法是一个空数组

 private static final int DEFAULT_CAPACITY = 10;
 private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
   public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

2.2:add()方法,往数组添加数据的时候会对size+1,判断是否需要扩容,默认是空数组,所以第一次添加元素的时候肯定会进行扩容为大小是10的数组,然后进行元素的拷贝。

  public boolean add(E e) {
   //确保数组容量足够
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    elementData[size++] = e;
    return true;
}
private void ensureCapacityInternal(int minCapacity) {
    ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
private static int calculateCapacity(Object[] elementData, int minCapacity) {
    //空数组的话,设置容量大小为10,见构造方法代码块
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        return Math.max(DEFAULT_CAPACITY, minCapacity);
    }
    return minCapacity;
}
  private void ensureExplicitCapacity(int minCapacity) {
    modCount++;
    //判断是否需要扩容
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}



private void grow(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length;
    //通过位运算,右移一位进行1.5倍扩容
    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);
}

2.3:remove()
判断是否越界,越界则抛异常,然后进行数据的拷贝。

public E remove(int index) {
    
    rangeCheck(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

    return oldValue;
}

private void rangeCheck(int index) {
    if (index >= size)
        throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}

2.4:get()

  public E get(int index) {
      //检查是否越界
    rangeCheck(index);
      //fail-fast 防止用户多线程操作
    checkForComodification();
    return ArrayList.this.elementData(offset + index);
}
private void checkForComodification() {
    //相当于一个版本号,判断版本号是否是预期的值
    if (ArrayList.this.modCount != this.modCount)
        throw new ConcurrentModificationException();
}
E elementData(int index) {
    return (E) elementData[index];
}

三:总结

优点:ArrayList进行读操作,通过下标进行随机访问,时间复杂度logO(1),性能高。
缺点:频繁进行插入操作,需要考虑扩容和拷贝操作,性能较差。

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

打赏
文章很值,打赏犒劳作者一下
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页

打赏

任我行哟

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者