ArrayList的特点及应用场景
ArrayList的特点及应用场景
一、ArrayList核心特点
-
基于动态数组实现
-
底层使用Object[]数组存储元素
-
默认初始容量为10
-
扩容机制:每次扩容为原来的1.5倍(
int newCapacity = oldCapacity + (oldCapacity >> 1)
)
-
-
快速随机访问
-
实现了RandomAccess接口(标记接口)
-
通过索引访问元素的时间复杂度为O(1)
-
-
有序可重复
-
保持插入顺序
-
允许存储重复元素和null值
-
-
非线程安全
-
多线程环境下需要外部同步
-
可以使用
Collections.synchronizedList
包装
-
-
插入删除效率
-
尾部操作:O(1)
-
中间操作:O(n)(需要移动元素)
-
二、与LinkedList对比
特性 | ArrayList | LinkedList |
---|---|---|
底层结构 | 动态数组 | 双向链表 |
随机访问 | O(1) | O(n) |
头部插入/删除 | O(n) | O(1) |
尾部插入/删除 | O(1) | O(1) |
内存占用 | 较小(仅存储实际元素) | 较大(需要存储前后节点引用) |
三、典型应用场景
-
适合使用ArrayList的场景
-
频繁访问元素(按索引读取)
// 数据查询业务 List<Product> productList = new ArrayList<>(); Product p = productList.get(5); // 高效随机访问
-
尾部频繁添加/删除
// 日志记录收集 List<Log> logs = new ArrayList<>(); logs.add(newLog); // 尾部添加高效
-
数据量可预估且变化不大
// 初始化时指定容量避免扩容 List<String> fixedSizeList = new ArrayList<>(1000);
-
-
不适合使用ArrayList的场景
-
频繁在列表中间插入/删除
-
内存空间非常紧张的情况
-
需要线程安全但未做同步处理
-
四、最佳实践建议
-
初始化指定容量(如果可以预估大小)
// 避免多次扩容 List<User> users = new ArrayList<>(expectedSize);
-
批量操作使用addAll
// 比循环add更高效 list.addAll(anotherCollection);
-
遍历方式选择
// 随机访问结构推荐使用for循环 for (int i = 0; i < list.size(); i++) {Item item = list.get(i); }// 或者使用迭代器 for (Item item : list) {// ... }
-
注意并发修改
// 多线程环境需要同步 List<String> syncList = Collections.synchronizedList(new ArrayList<>());
ArrayList因其出色的随机访问性能和空间效率,成为Java中最常用的集合类之一,特别适合"读多写少"和"尾部操作多"的场景。