1. ArrayList是什么?¶
在Java中,ArrayList是java.util包下的一个类,它实现了动态数组的功能。简单来说,ArrayList就像一个可以自动扩容的数组——我们不需要手动指定它的长度,当元素数量超过当前容量时,它会自动“长大”,也可以随时添加或删除元素,非常灵活。
与普通数组(如int[])相比,ArrayList的核心优势是长度可变,且提供了一系列便捷的方法来操作元素(增删改查、遍历等),适合存储和管理不确定长度的数据集合。
2. 为什么选择ArrayList?¶
假设我们需要存储一个班级的学生名单:
- 如果用普通数组,必须先定义固定长度(比如String[] students = new String[50]),但学生人数可能多于50,或少于50,容易造成空间浪费或数组越界。
- 如果用ArrayList,直接new ArrayList<String>()就能创建一个空列表,后续可以随时添加学生(add()方法),不需要担心长度问题。
此外,ArrayList还封装了很多实用方法(如排序、查找),让操作更简单,无需重复写数组相关的复杂逻辑。
3. 基本操作:创建与初始化¶
要使用ArrayList,首先需要导入java.util.ArrayList包,然后通过构造方法创建对象。泛型(<E>)用于指定列表中元素的类型(如字符串、整数等),避免类型错误。
import java.util.ArrayList; // 导入ArrayList类
public class ArrayListDemo {
public static void main(String[] args) {
// 创建一个存储String类型的ArrayList(空列表)
ArrayList<String> fruits = new ArrayList<>();
// 也可以指定初始容量(可选,提前规划容量可减少扩容次数)
ArrayList<Integer> numbers = new ArrayList<>(10); // 初始容量为10
}
}
4. 添加元素:add()方法¶
使用add(E e)方法可以在列表末尾添加元素,add(int index, E e)可以在指定位置插入元素。
// 1. 在末尾添加元素
fruits.add("苹果");
fruits.add("香蕉");
fruits.add("橙子");
// 2. 在指定位置插入元素(例如在索引1处插入“西瓜”)
fruits.add(1, "西瓜");
// 此时列表内容:[苹果, 西瓜, 香蕉, 橙子]
5. 获取元素:get()方法¶
通过get(int index)获取指定位置的元素,索引从0开始(如果索引超过列表长度或为负数,会抛出IndexOutOfBoundsException异常)。
// 获取第1个元素(索引0)
String first = fruits.get(0); // "苹果"
// 获取最后一个元素(索引为size()-1)
String last = fruits.get(fruits.size() - 1); // "橙子"
6. 修改元素:set()方法¶
使用set(int index, E element)替换指定位置的元素,并返回旧元素。
// 将索引1的元素(“西瓜”)替换为“葡萄”
String oldElement = fruits.set(1, "葡萄");
// 替换后列表:[苹果, 葡萄, 香蕉, 橙子]
// oldElement的值为“西瓜”
7. 删除元素:remove()方法¶
删除元素有两种方式:
- remove(int index):删除指定索引的元素,返回被删除的元素。
- remove(Object o):删除第一个与o匹配的元素(若有重复元素,仅删除第一个)。
// 1. 删除索引2的元素(“香蕉”)
String removed = fruits.remove(2); // 返回“香蕉”
// 删除后列表:[苹果, 葡萄, 橙子]
// 2. 删除元素“橙子”(注意:remove(对象)需要元素类型匹配)
fruits.remove("橙子");
// 删除后列表:[苹果, 葡萄]
8. 遍历ArrayList:如何打印所有元素?¶
遍历是使用列表的核心场景之一,常见方式有3种:
方式1:普通for循环(通过索引)¶
for (int i = 0; i < fruits.size(); i++) {
System.out.println(fruits.get(i)); // 逐个打印元素
}
方式2:增强for循环(for-each)¶
适合只需要遍历元素,不需要修改索引的场景。
for (String fruit : fruits) {
System.out.println(fruit); // 直接遍历元素
}
方式3:迭代器(Iterator)¶
适合需要边遍历边删除元素的场景(普通for循环删除会导致索引变化,容易出错)。
import java.util.Iterator;
Iterator<String> iterator = fruits.iterator();
while (iterator.hasNext()) {
String fruit = iterator.next();
System.out.println(fruit);
// 若需删除元素,使用iterator.remove()
// if (fruit.equals("葡萄")) iterator.remove();
}
9. 动态扩容:容量不够怎么办?¶
ArrayList会在添加元素时自动扩容:当元素数量超过当前容量时,它会创建一个新的数组(初始容量为10,之后每次扩容到原来的1.5倍左右),并将旧数组的元素复制到新数组中。
例如:
- 初始容量为10,添加10个元素后,容量已满;
- 再添加第11个元素时,容量会自动扩容到15(10的1.5倍),并复制所有元素到新数组。
注意:扩容是自动的,无需手动处理,这也是ArrayList的核心优势之一(不用担心“数组满了”的问题)。
10. 注意事项¶
- 索引越界:操作时索引必须在
0到size()-1之间,否则会报错(如get(-1)或remove(5)但列表只有3个元素)。 - 泛型约束:创建时指定的元素类型(如
<String>)必须统一,否则编译报错(无法添加其他类型元素)。 - 重复元素:
remove(Object o)只会删除第一个匹配的元素(若有重复,需多次调用)。
11. 完整示例¶
import java.util.ArrayList;
import java.util.Iterator;
public class ArrayListFullDemo {
public static void main(String[] args) {
// 1. 创建列表
ArrayList<String> animals = new ArrayList<>();
// 2. 添加元素
animals.add("猫");
animals.add("狗");
animals.add("兔子");
System.out.println("初始列表:" + animals); // [猫, 狗, 兔子]
// 3. 修改元素
animals.set(1, "老虎"); // 替换索引1的“狗”为“老虎”
System.out.println("修改后:" + animals); // [猫, 老虎, 兔子]
// 4. 删除元素
animals.remove(0); // 删除索引0的“猫”
System.out.println("删除后:" + animals); // [老虎, 兔子]
// 5. 遍历元素(增强for循环)
System.out.println("遍历元素:");
for (String animal : animals) {
System.out.println(animal);
}
// 6. 使用迭代器遍历
System.out.println("迭代器遍历:");
Iterator<String> it = animals.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
}
总结¶
ArrayList是Java中最基础也最常用的动态数组工具,掌握它的核心操作(增删改查、遍历)能帮你快速处理不确定长度的数据。记住:灵活、自动扩容、无需关心容量是它的三大优势,多动手练习(如存储学生信息、商品列表等场景)就能熟练掌握!
如果需要更复杂的操作(如排序、查找),可以后续学习Collections工具类或ArrayList的其他方法,但打好基础永远是关键。