Java ArrayList
ArrayList 是"可自动扩容的数组",按下标存取、查询飞快,是集合中最常用的实现类。它解决了数组长度固定、难以增删的痛点,适合"存得多、按位置读"的场景。
创建与常用方法
创建时建议用泛型声明元素类型。常用方法:add 添加、get 按下标取、set 修改、remove 删除、size 长度、contains 是否包含、isEmpty 是否为空、clear 清空。完整可运行示例:
import java.util.ArrayList;
public class ArrayListDemo {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("苹果");
list.add("香蕉");
list.add("橙子");
System.out.println(list); // 输出:[苹果, 香蕉, 橙子]
System.out.println(list.get(0)); // 输出:苹果
list.set(1, "葡萄"); // 把下标 1 改成葡萄
list.remove(2); // 删除下标 2
System.out.println(list); // 输出:[苹果, 葡萄]
System.out.println(list.size()); // 输出:2
System.out.println(list.contains("苹果")); // 输出:true
System.out.println(list.isEmpty()); // 输出:false
// list.clear(); // 清空所有元素
}
}
三种遍历方式
没有下标也能遍历,三种写法各有用途:
// 片段需放进 main 方法中运行(文件顶部需 import java.util.*)
List<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("C");
for (int i = 0; i < list.size(); i++) { // ① 普通 for:需要下标时
System.out.print(list.get(i));
}
for (String s : list) { // ② 增强 for:最简单
System.out.print(s);
}
Iterator<String> it = list.iterator(); // ③ Iterator:遍历中安全删除
while (it.hasNext()) {
System.out.print(it.next());
}
// 输出:ABCABCABC
与数组互转
toArray 把集合转成数组;Arrays.asList 把数组包装成 List,但大小固定,不能增删。
// 片段需放进 main 方法中运行(文件顶部需 import java.util.*)
List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
String[] arr = list.toArray(new String[0]); // 集合 → 数组
List<String> back = Arrays.asList(arr); // 数组 → 集合(固定大小)
// back.add("c"); // 运行时报错:UnsupportedOperationException
System.out.println(Arrays.toString(arr)); // 输出:[a, b]
底层原理:自动扩容
ArrayList 底层是 Object 数组:默认容量 10,装不下时按约 1.5 倍扩容,即"新建更大的数组 + 复制旧元素"。日常使用无需关心,了解它有助于理解性能差异。
按索引插入、删除的注意点
按下标 get 是 O(1);但 add(i, x) 会让后续元素整体后移,remove(i) 会让后续元素整体前移,都是 O(n) 操作。频繁在头部或中间增删,应改用 LinkedList。
// 片段需放进 main 方法中运行(文件顶部需 import java.util.*)
List<String> list = new ArrayList<>();
list.add("A");
list.add("C");
list.add(1, "B"); // 在下标 1 插入,C 整体后移
System.out.println(list); // 输出:[A, B, C]
list.remove(1); // 删除下标 1,C 整体前移
System.out.println(list); // 输出:[A, C]
小结:ArrayList = 可扩容数组,按下标读最快,适合频繁查询、元素动态增减的场景;中间频繁增删选 LinkedList,多线程共享则考虑 Vector 或 CopyOnWriteArrayList。它是进入集合世界的第一站,务必熟练。