Java ArrayList基础:动态数组操作,初学者必学

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. 注意事项

  • 索引越界:操作时索引必须在0size()-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的其他方法,但打好基础永远是关键。

小夜