ArrayList底层结构和源码分析

78 阅读2分钟

我正在参加「掘金·启航计划」

1. ArrayList 的注意事项

  1. permits all elements, including null , ArrayList可以加入null,并且多个。
	ArrayList arrayList = new ArrayList();
	arrayList.add(null);
	arrayList.add("兮动人");
	arrayList.add(null);
	System.out.println(arrayList);

在这里插入图片描述

  1. ArrayList是由 数组 来实现数据存储的
  2. ArrayList基本等同于Vector,除了ArrayList线程不安全(执行效率高) 。 看源码,如 :add 方法没有 synchronized (同步)修饰。 在多线程情况下,不建议使用ArrayList。
public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
}

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

  1. ArrayList中维护了一个Object类型的数组elementData。[debug看源码] transient Object[] elementData;transient表示瞬间,短暂的,表示该属性不会被序列化 在这里插入图片描述

  2. 当创建ArrayList对象时,如果使用的是无参构造器,则初始值elementData容量为0,第1次 添加,则扩容elementData10,如需要再次扩容,则扩容elementData1.5倍。 在这里插入图片描述

  • 无参构造器-扩容 在这里插入图片描述 在这里插入图片描述
  1. 如果使用的是指定大小的构造器,则初始elementData容量为指定大小,如果需要扩容,则直接扩容elementData1.5倍。
  • 指定大小的构造器--扩容 在这里插入图片描述 在这里插入图片描述
  • 建议:去debug一把我们的ArrayList的创建和扩容的流程。
  1. debug 查看 ArrayList 源码分析
	//使用无参构造器创建 ArrayList 对象
	//ArrayList list = new ArrayList();
	ArrayList list = new ArrayList(8);
	//使用 for 给 list 集合添加 1-10 数据
	for (int i = 1; i <= 10; i++) {
	list.add(i);
	}
	//使用 for 给 list 集合添加 11-15 数据
	for (int i = 11; i <= 15; i++) {
	list.add(i);
	}
	list.add(100);
	list.add(200);
	list.add(null);
  • 注意:Idea 默认情况下,Debug 显示的数据是简化后的,如果希望看到完整的数据,需要设置如下 在这里插入图片描述

  • ArrayList 无参构造分析:

  • 可以看到 ArrayList 第一次初始化后的 elementData 是个空数组 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

  • ArrayList 有参分析 在这里插入图片描述