ArrayList详解

目录

ArrayList详解

ArrayList的注意事项

ArrayList 的底层操作机制源码分析

分析使用无参构造器,创建和使用 ArrayList 的源码

分析使用有参构造器,创建和使用 ArrayList 的源码


ArrayList详解

ArrayList的注意事项

  • ArrayList 可以存放null,并且可以存放多个null

  • ArrayList 是由数组来实现数据存储的

  • ArrayList 中的方法没有用 sychronized 关键字修饰,所以线程不安全

  • ArrayList 基本等同于 Vector,除了 ArrayList 是线程不安全(执行效率高),因此在多线程情况下,不建议使用ArrayList

  • 返回上次跳转的位置的快捷键:ctrl + alt + 方向键

  • 格式化代码块:ctrl + alt + L

ArrayList 的底层操作机制源码分析

  • ArrayList 中维护了一个Object类型的数组elementData

    • transient Object[] elementData; // transient 表示瞬间,短暂的,表示该属性不会被序列化

  • 当创建 ArrayList 对象时,如果使用的是无参构造器,则初始elementData容量为0,第1次添加,则扩容elementData10,如需要再次扩容,则扩容为elementData1.5

  • 如果使用的是指定大小的构造器,则初始elementData容量为指定大小,如果需要扩容,则直接扩容为elementData1.5

分析使用无参构造器,创建和使用 ArrayList 的源码

public class Demo03 {
    public static void main(String[] args) {
        ArrayList list = new ArrayList();
        for (int i = 1; i <=10; i++) {
            list.add(i);
        }
        for (int i = 11; i <=15; i++) {
            list.add(i);
        }
        list.add(100);
        list.add(200);
        list.add(null);
​
    }
}


  • 1.执行 ArrayList list = new ArrayList();

    • 创建了一个空的 elementData 数组

public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
  • 2.执行 List.add(E e)

    1. ensureCapacityInternal(size + 1); , 先确定是否需要扩容

    2. 然后再执行赋值

public boolean add(E e) {
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    elementData[size++] = e;
    return true;
}
  • 3.执行ensureCapacityInternal(size + 1); ,该方法确定 minCapacity

    • 第一次扩容为10

private static int calculateCapacity(Object[] elementData, int minCapacity) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        return Math.max(DEFAULT_CAPACITY, minCapacity);
    }
    return minCapacity;
}
​
private void ensureCapacityInternal(int minCapacity) {
    ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
  • 4.执行 ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));

    • modCount++; 记录集合被修改的次数,防止多线程的操作出现异常

    • 如果 elementData 的大小不够,就调用 grow() 去扩容

private void ensureExplicitCapacity(int minCapacity) {
    modCount++;
​
    // overflow-conscious code
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}
  • 5.执行 grow(minCapacity);

    • 真的进行扩容

    • 使用扩容机制来确定要扩容到多大

    • 第一次 newCapacity = 10

    • 第二次及其以后,newCapacity 按照1.5倍进行扩容

    • 扩容使用的是 Arrays.copyOf()

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);
}

分析使用有参构造器,创建和使用 ArrayList 的源码

public class Demo03 {
    public static void main(String[] args) {
        ArrayList list = new ArrayList(8);
        for (int i = 1; i <=10; i++) {
            list.add(i);
        }
        for (int i = 11; i <=15; i++) {
            list.add(i);
        }
        list.add(100);
        list.add(200);
        list.add(null);
​
    }
}


  • 1.执行 ArrayList list = new ArrayList(8);

    • 创建了一个指定大小为 8 的elementData数组

    • this.elementData = new Object[initialCapacity];

public ArrayList(int initialCapacity) {
    if (initialCapacity > 0) {
        this.elementData = new Object[initialCapacity];
    } else if (initialCapacity == 0) {
        this.elementData = EMPTY_ELEMENTDATA;
    } else {
        throw new IllegalArgumentException("Illegal Capacity: "+
                                           initialCapacity);
    }
}

使用有参构造器的扩容机制:

第一次扩容时,就按照elementData的1.5倍进行扩容,其余的流程和无参构造器一样

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值