东东
发布于 2022-10-09 / 24 阅读 / 0 评论 / 0 点赞

ArrayList

回顾List的特点:

  • 有序列表
  • 元素可以重复

概述:

先看代码:

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
  • 继承于AbstractList,实现了List接口,是一个长度可变的集合,提供了增删改查的功能。
  • 实现了RandomAccess接口,可以对元素进行快速访问。
  • 实现了Serializable接口,说明ArrayList可以被序列化。
  • 实现了Cloneable接口,可以被复制。
  • 允许null的存在,允许数据重复。
  • 非线程安全的。

底层实现原理

1、实现:

Object数组

2、特点:

查询快、增删慢

容量

1、默认容量

  1. 使用无参构造器,默认容量为0,
  2. 使用有参构造器,容量为参数值。

2、扩容机制

add()的扩容机制

当容量不够时,自动进行扩容:

  1. 若原本容量为0,则首次扩容容量调整为10;
  2. 若原本容量不为0,新数组的容量调整为原来数组容量的1.5倍;
  3. 将老数组的数据复制一份到新数组。
private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        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);
    }

addAll()的扩容机制

在下次扩容容量和实际添加元素的个数之间取最大值。

  • 当前没有元素,下次扩容应该是10个,添加三个元素,最终容量应该为10
  • 当前10个元素,下次扩容应该是15个,添加六个元素,最终容量应该为16

添加元素

1、在指定位置添加元素

  1. 先复制一份数组到新数组;
  2. 判断有没有空间,若没有空间则需要进行扩容;
  3. 将指定位置的元素以及后面的元素统一向后移动一位;
  4. 在指定位置放入新的元素。

2、在数组末尾进行元素添加:

  1. 直接将数组的长度加一;
  2. 在末尾放入新元素。