Java ArrayList的介绍及用法
十分想念顺店杂可。。。
ArrayList
是 Java 集合框架中最常用的类之一,实现了 List
接口,底层基于动态数组实现,支持动态扩容,相比普通数组更灵活。以下是其详细介绍及用法:
一、核心特性
- 动态大小:无需预先指定容量,可自动扩容(初始容量为 10,满后扩容为原容量的 1.5 倍)。
- 允许重复元素:可存储多个相同值的元素。
- 有序集合:元素按插入顺序排列,支持通过索引访问。
- 非线程安全:多线程环境下并发修改可能导致异常(需手动同步或使用
CopyOnWriteArrayList
)。 - 存储引用类型:只能存储对象(基本类型需用包装类,如
Integer
而非int
)。
二、基本用法(代码示例)
1. 引入包与创建对象
ArrayList
位于 java.util
包,需先导入,创建时需指定泛型(元素类型):
import java.util.ArrayList;
import java.util.List;public class ArrayListDemo {public static void main(String[] args) {// 创建存储String类型的ArrayList(推荐声明为List接口)List<String> list = new ArrayList<>();// 可指定初始容量(减少扩容次数,优化性能)List<Integer> numList = new ArrayList<>(20); // 初始容量20}
}
2. 常用方法
(1)添加元素:add()
List<String> list = new ArrayList<>();
list.add("Java"); // 末尾添加元素 → [Java]
list.add(0, "Python"); // 指定索引插入 → [Python, Java](索引需≤当前size)
list.addAll(List.of("C", "C++")); // 批量添加 → [Python, Java, C, C++]
(2)访问元素:get()
通过索引获取元素(索引从 0 开始,需注意 IndexOutOfBoundsException
):
String first = list.get(0); // 获取第1个元素 → "Python"
int size = list.size(); // 获取元素个数 → 4
(3)修改元素:set()
替换指定索引的元素,返回被替换的旧值:
String old = list.set(1, "JavaScript"); // 替换索引1的元素 → 旧值"Java"
// 此时list为 [Python, JavaScript, C, C++]
(4)删除元素:remove()
String removed = list.remove(2); // 移除索引2的元素 → 返回"C",list变为 [Python, JavaScript, C++]
boolean isRemoved = list.remove("C++"); // 移除指定值的元素 → 返回true,list变为 [Python, JavaScript]
(5)判断与查找
boolean isEmpty = list.isEmpty(); // 判断是否为空 → false
boolean contains = list.contains("Python"); // 是否包含指定元素 → true
int index = list.indexOf("JavaScript"); // 首次出现的索引 → 1
int lastIndex = list.lastIndexOf("Python"); // 最后出现的索引 → 0(元素唯一时与indexOf相同)
(6)清空与截取
list.clear(); // 清空所有元素 → list变为空
List<String> subList = list.subList(0, 2); // 截取子列表(从索引0到2,不含2)→ [Python, JavaScript]
3. 遍历方式
(1)普通 for 循环(通过索引)
for (int i = 0; i < list.size(); i++) {System.out.println(list.get(i));
}
(2)增强 for 循环(foreach)
for (String element : list) {System.out.println(element);
}
(3)迭代器(Iterator
)
支持在遍历中安全删除元素:
import java.util.Iterator;Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {String element = iterator.next();if (element.equals("Python")) {iterator.remove(); // 安全删除当前元素}
}
(4)Java 8+ 流(Stream)
list.stream().forEach(System.out::println); // 简化遍历
三、注意事项
扩容机制:当元素数量超过当前容量时,ArrayList 会自动扩容为原容量的 1.5 倍(通过
Arrays.copyOf()
复制数组)。若预知元素数量,创建时指定初始容量可减少扩容次数(提升性能)。与数组的转换:
// ArrayList → 数组 String[] arr = list.toArray(new String[0]); // 推荐传递类型数组,避免强制转换// 数组 → ArrayList(注意:返回的是固定大小的List,不能添加/删除元素) List<String> fixedList = Arrays.asList(arr); // 若需可变List,需再包装一次: List<String> mutableList = new ArrayList<>(Arrays.asList(arr));
与 LinkedList 的对比:
ArrayList
基于数组,随机访问快(get(index)
时间复杂度 O (1)),增删中间元素慢(需移动元素,O (n))。LinkedList
基于链表,增删中间元素快(O(1)),随机访问慢(O(n))。- 频繁查改选
ArrayList
,频繁增删中间元素选LinkedList
。
线程安全:多线程环境下,可使用
Collections.synchronizedList()
包装:List<String> safeList = Collections.synchronizedList(new ArrayList<>());
四、总结
ArrayList
是日常开发中最常用的 List 实现,以动态数组为核心,兼顾灵活性与访问效率,适合大多数场景。掌握其 add()
、get()
、remove()
等方法及遍历方式,结合扩容机制和线程安全特性,可更高效地使用。