目录
前言
1. List接口的基本信息
2. ArrayList
2.1.ArrayList 的基本信息
2.2. ArrayList 的构造方法
2.2.1 ArrayList 的构造方法一
2.2.2 ArrayList 的构造方法二
2.2.3 ArrayList 的构造方法三
2.3 ArrayList 的扩容方式
总结
前言
Java 语言由于其跨平台、社区良好等特性,在企业级应用、移动应用、互联网开发等领域广泛应用。今天,让我们来认识一下 java.util 包下的 ArrayList 集合框架
1. List接口的基本信息
根据源码所知:
代码文档的作者:乔什·布洛赫(Josh Bolch)和尼尔·盖夫特(Neal Gafter)
- List 接口继承自Collection接口
- List 的实现类:
- ArrayList
- LinkedList
- Vector
- List 的抽象类:
- AbstractList
- AbstractSequentialList
- 代码起始版本:Java 1.2
2. ArrayList
2.1.ArrayList 的基本信息
根据源码所知:
- ArrayList 继承自抽象类 AbstractList
- ArrayList 实现的接口:
- List 接口:表示一个有序的集合
- RandomAccess:标记接口,用于标识支持高效随机访问的集合
- Cloneable:支持克隆(Clone)操作
- java.io.Serializable:可以将当前类的对象转换为字节序列,以便在网络传输和保存到文件
根据源码所知:
- serialVersionUID :这是用于序列化和反序列化 ArrayList 对象时的版本号。当对 ArrayList 类进行修改时,需要更新该版本号,以确保序列化和反序列化的兼容性。
- int DEFAULT_CAPACITY = 10:默认的初始容量值,表示当没有指定容量时,ArrayList 的初始容量为 10。
- Object[ ] EMPTY_ELEMENTDATA = { }: 这是一个空的 Object 数组,用于表示空的 ArrayList 实例。
- Object[ ] DEFAULTCAPACITY_ELEMENTDATA = { }: 这也是一个空的 Object 数组,与 EMPTY_ELEMENTDATA 不同之处在于,当第一个元素被添加时,如果 elementData 数组等于 DEFAULTCAPACITY_EMPTY_ELEMENTDATA,它将会被扩容为默认容量 DEFAULT_CAPACITY。
- transient Object [ ] elementData:存储 ArrayList 元素的数组缓冲区。ArrayList 的容量等于这个数组缓冲区的长度。当 elementData 等于 DEFAULTCAPACITY_EMPTY_ELEMENTDATA 时,表示 ArrayList 是空的,并且当第一个元素被添加时,会将其扩容为默认容量。
2.2. ArrayList 的构造方法
2.2.1 ArrayList 的构造方法一
根据源码所知:
这个构造方法接受一个整型参数,其中 initialCapacity 表示初始化 ArrayList 的初始容量
- 如果 initialCapacity 大于0,则初始化 elementData 数组为指定容量的 Object 数组。
- 如果 initialCapacity 等于0,则将 elementData 数组初始化为空的常量EMPTY_ELEMENTDATA。
- 如果 initialCapacity 小于0,则抛出 IllegalArgumentException 异常,提示传入的容量参数不合法。
2.2.2 ArrayList 的构造方法二
根据源码所知:
这是一个无参构造方法,用于构造一个空列表,初始容量为默认的大小。
- 默认的空列表会将 elementData 数组初始化为DEFAULTCAPACITY_EMPTY_ELEMENTDATA。
2.2.3 ArrayList 的构造方法三
根据源码所知:
这个构造方法接受一个类型为Collection的参数c,用于构造一个包含指定集合元素的ArrayList。
- 将集合c转换为数组,并赋值给 elementData。
- 获取数组的长度作为列表的大小 size。
- 如果数组的长度不为0,针对可能出现的类型转换问题进行处理,确保elementData是Object[] 类型。
- 如果数组长度为0,将elementData初始化为空的常量EMPTY_ELEMENTDATA。
2.3 ArrayList 的扩容方式
根据源码所知:
- 当 ArrayList 需要进行扩容时,会调用 grow(int minCapacity)方法。这个方法会计算出新的容量值 newCapacity
- 通常情况下,新容量值是旧容量的1.5倍(即
oldCapacity + (oldCapacity >> 1)
)- 接着会判断是否超出了最大数组容量(2^31 - 1 - 8),如果超出则调用 hugeCapacity 方法进行处理
- 最后,通过调用 Arrays.copyOf 方法,将原数组的内容复制到新的具有更大容量的数组中,完成扩容操作
根据源码所知:
- 当数组容量的新容量超出最大数组容量(2^31 - 1 - 8)时调用hugeCapacity 方法进行处理,如果需要的最小容量 minCapacity 小于 0,则会抛出 OutOfMemoryError 异常
- 如果需要的最小容量 minCapacity 超出数组最大容量(2^31 - 1 - 8),则返回 2^31 - 1 给新容量,否则返回数组最大容量 2^31 - 1 -8
总结
- ArrayList 继承自 AbstractList 抽象类
ArrayList 的应用场景:
- ArrayList 的数据结构为 Object[ ] 数组,实现了 RandomAccess 接口,支持高效随机访问和克隆操作。适用于遍历、查找等读取数据元素的应用场景。
- ArrayList 实现了 java.io.Serializable ,可以被序列化为字节序列,以便在网络传输和保存到文件
ArrayList 的扩容方式:
- 使用无参构造方法创建 ArrayList 时,实际上初始化赋值是一个空数组,当向数组中添加第一个元素时,数组容量扩容为10
- 当数组容量不足时,调用 grow() 方法进行扩容,每次扩容后容量会变为原来的 1.5 倍左右
- ArrayList 的最大容量为 2^31 - 1 或 2^31 -1 -8