List集合之ArrayList

1.ArrayList 概述

在这里插入图片描述

  • ArrayList 继承自 AbstractList,实现了 List 接口,底层基于数组实现了动态的扩容机制,在物理内存上采用顺序存储结构,即数组。因此可根据索引快速的查找元素,还具有基于索引操作元素的一套方法,允许 null 元素的存在
  • 同时还实现了 RandomAccess 标志性接口,这意味着这个集合支持 快速随机访问策略,那么使用传统 for 循环的方式遍历数据会优于用迭代器遍历数据,即使用 get()方法获取数据相比于迭代器遍历更加快速
  • ArrayList 还实现了 Cloneable、Serializable 两个标志性接口,所以 ArrayList 支持克隆、序列化

2. ArrayList 源码解读

2.1. 主要类属性

// 如果不指定容量(空构造器),则在添加数据时的空构造器默认初始容量最小为 10
private static final int DEFAULT_CAPACITY = 10;

// 出现在需要用到空数组的地方,其中一处是使用自定义初始容量构造方法时候如果你指定初始容量为0的时候,那么elementData指向该数组。另一处是使用包含指定collection集合元素的列表的构造方法时,如果被包含的列表中没有数据,那么elementData指向该数组
private static final Object[] EMPTY_ELEMENTDATA = {
   };

// 如果使用默认构造方法,那么elementData指向该数组。在添加元素时会判断是否是使用默认构造器第一次添加,如果是数组就会扩容至10个容量
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {
   };

// 默认未初始化的储存 ArrayList集合元素的底层数组,其长度就是 ArrayList的容量
transient Object[] elementData;

// 私有的elementData数组中具体的元素对象的数量,可通过size方法获得。默认初始值为0,在add、remove等方法时size会改变
private int size;

2.2. 构造器与初始化容量

2.2.1. 默认的构造器 ArrayList()

public ArrayList() {
   
	// 如果使用默认构造方法,那么 elementData 指向该数组
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

使用空构造器时,其实当我们第一次为 ArrayList 添加元素的时候,底层数组扩容到了至少 10。这在动态扩容机制中会讲到

2.3. add() 方法与动态扩容机制(重点

  • ArrayList 不像数组那样,它能屈能伸,所以它实现了动态的扩容。一旦在添加元素的时候,发现容量用满了即 minCapacity - elementData.length > 0 = false 时,就按照原来数组的 1.5 倍(oldCapacity >> 1)进行扩容,扩容之后,再将原有的数组复制到新分配的内存地址上 Arrays.copyOf(elementData, newCapacity)
  • 触发 ArrayList 动态扩容的条件是 minCapacity - elementData.length > 0 是否为 true。为 true 则触发;反之,不会触发
public boolean add(E e) {
   
    // 判断并进行数组的扩容 or 长度超限的方法
    ensureCapacityInternal(size + 1);
    // 为 size的所在索引赋值,并且 size 自增 1
    elementData[size++] = e;
    return true;
}
  • size 是当前集合拥有的元素个数,不是容量大小,且未算进准备新增的元素
  • size + 1 是保证新进入的元素能满足要求
// minCapacity 最小容量,此时 minCapacity = size + 1
private void ensureCapacityInternal(int minCapacity) {
   
    // 如果是采用空构造器初始化集合,并且第一次添加元素
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
   
        // minCapacity 设置为 DEFAULT_CAPACITY 和 minCapacity 的最大值
        minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
    }
    // 走下一个方法,判断是否需要扩容 or 判断数组长度是否溢出
    ensureExplicitCapacity(minCapacity);
}

/**
 * 判断是否需要走扩容or判断数组长度是否可能溢出
 * @param minCapacity 最小容量
 */
private void ensureExplicitCapacity(int minCapacity) {
   
    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值