🟦 Java ArrayList 详解
1️⃣ 什么是 ArrayList?
ArrayList
是 Java 集合框架(java.util
包)中的一个类。- 本质:基于 动态数组 实现的 可变长列表。
- 特点:
- 元素有序(插入顺序就是存储顺序)。
- 允许存放 重复元素。
- 允许存放
null
。 - 底层通过 数组扩容机制 实现自动增长。
👉 和 数组 (array[])
的区别:
- 数组:长度固定,声明时必须指定大小。
ArrayList
:长度可变,存放的元素数量可以动态增减。
2️⃣ ArrayList 的定义与初始化
import java.util.ArrayList;
public class TestArrayList {
public static void main(String[] args) {
// 1. 创建一个空的 ArrayList(默认容量为 10)
ArrayList<String> list1 = new ArrayList<>();
// 2. 指定初始容量
ArrayList<Integer> list2 = new ArrayList<>(20);
// 3. 通过另一个集合初始化
ArrayList<String> list3 = new ArrayList<>(list1);
}
}
3️⃣ 常用方法
(1)添加元素
ArrayList<String> list = new ArrayList<>();
list.add("苹果");
list.add("香蕉");
list.add("橙子");
// 在指定位置插入
list.add(1, "草莓"); // [苹果, 草莓, 香蕉, 橙子]
(2)访问元素
String fruit = list.get(2); // 获取下标为 2 的元素 -> 香蕉
(3)修改元素
list.set(0, "榴莲"); // 修改下标 0 的元素 -> [榴莲, 草莓, 香蕉, 橙子]
(4)删除元素
list.remove(1); // 按下标删除 -> 删除草莓
list.remove("橙子"); // 按对象删除 -> 删除橙子
list.clear(); // 清空所有元素
(5)查询
list.add("苹果");
list.add("香蕉");
System.out.println(list.contains("苹果")); // true
System.out.println(list.indexOf("苹果")); // 0
System.out.println(list.isEmpty()); // false
System.out.println(list.size()); // 2
4️⃣ 遍历方式
ArrayList<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("C");
// 1. for 循环
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
// 2. 增强 for 循环
for (String item : list) {
System.out.println(item);
}
// 3. Iterator 迭代器
import java.util.Iterator;
Iterator<String> it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
// 4. Java 8 Lambda 表达式
list.forEach(e -> System.out.println(e));
5️⃣ ArrayList 底层原理(扩容机制)
- 底层是 动态数组(
Object[] elementData
)。 - 默认初始容量 = 10。
- 当元素数量 > 当前数组容量时,会 自动扩容:
- 新容量 = 原容量 × 1.5 (即增加 50%)。
- 把旧数组数据拷贝到新数组。
👉 因此:
- 频繁扩容会有性能开销(复制数组)。
- 如果能预估数据量,建议在创建时指定容量:
ArrayList<Integer> list = new ArrayList<>(1000);
6️⃣ 与 LinkedList 的区别
特点 | ArrayList | LinkedList |
---|---|---|
底层实现 | 动态数组 | 双向链表 |
随机访问 | O(1) 速度快 | O(n) 速度慢 |
插入删除 | 中间位置较慢(需要移动元素) | 任意位置都较快(只需修改指针) |
内存开销 | 较小 | 较大(存储指针) |
👉 使用建议:
- 随机访问多(如根据下标访问元素):用
ArrayList
。 - 频繁插入删除:用
LinkedList
。
7️⃣ 常见坑 ⚠️
- 边遍历边删除会出错
for (String item : list) { if (item.equals("A")) { list.remove(item); // ❌ 会报 ConcurrentModificationException } }
✅ 正确写法:用Iterator
Iterator<String> it = list.iterator(); while (it.hasNext()) { if (it.next().equals("A")) { it.remove(); // 正确 } }
- 线程不安全
ArrayList
不是线程安全的。- 多线程环境用
Collections.synchronizedList()
或CopyOnWriteArrayList
。
8️⃣ 使用场景
- 存储一组有序数据,需要 快速随机访问。
- 适合存放 查询多、修改少 的数据。
- 常用于缓存、批量处理、需要排序的场景。
📝 总结
- ArrayList 本质:动态数组,可自动扩容。
- 特点:有序、允许重复、可存
null
。 - 底层机制:默认容量 10,扩容为 1.5 倍。
- 优点:查询快。
- 缺点:插入删除慢、线程不安全。
- 最佳实践:查询多 → ArrayList,增删多 → LinkedList。
发表回复