java集合类(二)- ArrayList原码分析

目录

前言

原码分析

继承关系

类中属性

构造函数

核心方法

总结


前言

     ArrayList是可以动态增长和缩减的索引序列,他是基于数组实现的list类。

  • 不同于数组,ArrayList可以自增减
  • ArrayList支持随机访问,查询效率高,增加、删除效率低
  • 非线程安全

原码分析

接下来我们针对其原码做以下分析:继承关系类中属性构造函数核心方法 四个方面分析

       

AbstractList:抽象类封装了通用的list集合操作

RandomAccess:标记接口,表明它们支持快速随机访问

Cloneable:支持接口,实现Cloneable接口,支持Object.clone()方法(CloneNotSupportedException)

java.io.Serializable:标记接口,支持序列化

继承关系

       java集合类(二)- ArrayList原码分析_第1张图片

类中属性

           java集合类(二)- ArrayList原码分析_第2张图片

  • serialVersionUID:序列化编号
  • DEFAULT_CAPACITY:集合的初始化容量
  • DEFAULTCAPACITY_EMPTY_ELEMENTDATA:默认的空数组对象
  • EMPTY_ELEMENTDATA:空数组对象
  • MAX_ARRAY_SIZE:集合元素数组的最大值
  • elementData:集合的元素数组对象
  • size:集合的大小
  • modCount:来源AbstractList,迭代器使用,多线程并发修改触发fail-fast机制

备注:elementData arrayList底层是数组,实际元素存在数组elementData

           modCount记录当前集合被修改的次数,当我们遍历集合时调用集合的add(),remove()等方法时,modecount值会被改变;而迭代器记录的还是原来的还是遍历之前的值,不一致则说明多个线程再同时操作集合,为了保证结果的准确性抛异常ConcurrentModificationException

构造函数

       java集合类(二)- ArrayList原码分析_第3张图片

核心方法

       接下来我们从初始化、新增、修改、查询、删除分析下原码

/**
 * ArrayList数据结构
 *   ArrayList底层是数组,集合的操似对数组的操作
 * . 主要结构成员:DEFAULT_CAPACITY、elementData、size ...
 * . 集合操作流程(初始化、增、删、改、查)
 */
@Test
public void testArrayList() {
    //初始化
    List list = new ArrayList();
    //新增
    list.add("a1");
    log.info("添加元素a1到集合list:{}", list);
    //修改
    list.set(0, "a11");
    log.info("修改位置为0的集合元素list:{}", list);
    //查询
    log.info("查询位置0的集合元素:{}", list.get(0));
    //删除
    list.remove(0);
    log.info("删除集合元素后:{}", list);
}

//初始化 List list = new ArrayList();

      无参构造函数构建一个默认容量为10的空集合;集合第一次添加元素方可同步默认容量;

      java集合类(二)- ArrayList原码分析_第4张图片

      java集合类(二)- ArrayList原码分析_第5张图片

//新增 list.add("a1");

List.add()会在集合数组的末尾添加元素E

  1. 确保添加元素后集合空间充足
    1. 计算集合保存元素需要空间,如果集合元素为缺省空数组,在默认容量DEFAULT_CAPACITY = 10和size+1之间取最大值;否则集合需要空间为size+1
    2. 集合修改次数modCount+1
    3. 判断是否需要扩容:如果size+1>elementData.length,执行扩容方法grow()
  2. 数组末尾添加新元素
  3. 当前集合的size+1

java集合类(二)- ArrayList原码分析_第6张图片

java集合类(二)- ArrayList原码分析_第7张图片

ensureCapacityInternal()方法

        calculateCapacity()方法

        java集合类(二)- ArrayList原码分析_第8张图片

ensureExplicitCapacity()方法

java集合类(二)- ArrayList原码分析_第9张图片

grow()方法

java集合类(二)- ArrayList原码分析_第10张图片

//修改 list.set(0, "a11");

  • 获得索引的原元素
  • 替换数组在当前索引的值为新元素
  • 返回原元素

//查询 list.get(0) ;

java集合类(二)- ArrayList原码分析_第11张图片

//删除 list.remove(0);

 

  • 验证删除的索引位置是否越界
  • 修改计数器+1
  • 查询当前修改位置的元素
  • 计算需要移动的元素个数
  • 索引之后的元素向前移动1
  • 集合的原最后位置赋值为null
  • 返回删除的元素

java集合类(二)- ArrayList原码分析_第12张图片                java集合类(二)- ArrayList原码分析_第13张图片

总结

  • ArrayList本质上是一个elementDate数组
  • ArrayList集合的大小≠elementDate数组的长度
  • ArrayList支持存放null
  • ArrayList实现了RandomAccess,标记支持随机访问
  • ArrayList由于底层是数组(固定长度),扩容或者缩容时会移动较多元素

你可能感兴趣的:(java-基础)