杰瑞科技汇

java arraylist的用法

目录

  1. 什么是 ArrayList
  2. ArrayList vs 数组
  3. ArrayList 的基本用法
    • 创建和初始化
    • 添加元素
    • 获取元素
    • 修改元素
    • 删除元素
    • 获取大小
  4. ArrayList 的常用方法详解
  5. ArrayList 的遍历方式
  6. ArrayList 的注意事项
    • 线程安全性
    • 泛型
    • null
  7. 实战示例

什么是 ArrayList

ArrayList 是 Java 集合框架中 List 接口的一个实现类,它的底层是一个动态数组,也就是说,它的容量是可以自动增长的。

java arraylist的用法-图1
(图片来源网络,侵删)
  • 特点
    • 有序:元素的存取顺序是一致的。
    • 可重复:可以存储重复的元素。
    • 动态扩容:当元素数量超过当前容量时,ArrayList 会自动扩容(通常是原容量的 1.5 倍)。
    • 随机访问快:基于数组实现,可以通过索引(下标)快速访问任意位置的元素,时间复杂度为 O(1)。
    • 增删中间元素慢:在中间插入或删除元素时,需要移动大量元素,时间复杂度为 O(n)。

ArrayList vs 数组

在深入 ArrayList 之前,先理解它和传统数组的区别非常重要。

特性 数组 ArrayList
大小 固定,创建时必须指定大小,之后无法改变。 动态,可以随时添加或删除元素,大小自动调整。
类型 可以存储基本类型(如 int[])和对象(如 String[])。 只能存储对象,对于基本类型,需要使用其对应的包装类(如 Integer 代替 int)。
功能 功能简单,只有 length 属性和一些基本操作。 功能丰富,提供了大量方法,如 add(), remove(), size(), sort() 等。
性能 访问速度快,增删慢(因为大小固定)。 随机访问快,增删中间元素慢。

如果你需要存储一个固定数量、已知类型的数据,数组是轻量级的选择,如果你需要一个可以动态改变大小的集合,并且需要丰富的操作方法,ArrayList 是不二之选。


ArrayList 的基本用法

1 创建和初始化

最常用的方式是使用泛型来指定 ArrayList 中要存储的元素类型。

// 1. 创建一个空的、初始容量为 10 的 ArrayList
// 推荐使用泛型,指定存放 String 类型
ArrayList<String> stringList = new ArrayList<>();
// 2. 创建一个指定初始容量的 ArrayList
// 如果大概知道要存多少元素,可以指定初始容量以减少扩容操作
ArrayList<Integer> numberList = new ArrayList<>(20);
// 3. 使用集合初始化(Java 9+)
// List.of() 创建的是一个不可变列表,不能添加或删除元素
// 如果需要一个可变的 ArrayList,可以这样转换
List<String> initialList = List.of("Apple", "Banana", "Cherry");
ArrayList<String> fruitList = new ArrayList<>(initialList);

2 添加元素

使用 add() 方法。

java arraylist的用法-图2
(图片来源网络,侵删)
ArrayList<String> colors = new ArrayList<>();
// 在列表末尾添加元素
colors.add("Red");
colors.add("Green");
colors.add("Blue");
// 在指定位置插入元素
colors.add(1, "Yellow"); // 在索引 1 的位置插入 "Yellow"
// colors 现在是: ["Red", "Yellow", "Green", "Blue"]

3 获取元素

使用 get(int index) 方法,索引从 0 开始。

ArrayList<String> colors = new ArrayList<>(List.of("Red", "Green", "Blue"));
String firstColor = colors.get(0); // 获取第一个元素
System.out.println("The first color is: " + firstColor); // 输出: The first color is: Red

4 修改元素

使用 set(int index, E element) 方法。

ArrayList<String> colors = new ArrayList<>(List.of("Red", "Green", "Blue"));
// 修改索引 1 处的元素
colors.set(1, "Orange");
// colors 现在是: ["Red", "Orange", "Blue"]
System.out.println(colors); // 输出: [Red, Orange, Blue]

5 删除元素

有两种常用方式:

  • remove(int index):删除指定索引位置的元素。
  • remove(Object o):删除第一个匹配的元素。
ArrayList<String> colors = new ArrayList<>(List.of("Red", "Green", "Blue", "Green"));
// 删除索引为 2 的元素
colors.remove(2); // 删除 "Blue"
// colors 现在是: ["Red", "Green", "Green"]
// 删除第一个值为 "Green" 的元素
colors.remove("Green");
// colors 现在是: ["Red", "Green"]

6 获取大小

使用 size() 方法,它返回列表中的元素数量。

java arraylist的用法-图3
(图片来源网络,侵删)
ArrayList<String> colors = new ArrayList<>(List.of("Red", "Green", "Blue"));
int size = colors.size();
System.out.println("The size of the list is: " + size); // 输出: The size of the list is: 3

ArrayList 的常用方法详解

方法 描述
add(E e) 将指定的元素追加到此列表的末尾。
add(int index, E element) 在此列表的指定位置插入指定的元素。
get(int index) 返回此列表中指定位置的元素。
set(int index, E element) 用指定的元素替换此列表中指定位置的元素。
remove(int index) 移除此列表中指定位置的元素。
remove(Object o) 移除此列表中首次出现的指定元素(如果存在)。
size() 返回此列表中的元素数。
isEmpty() 如果此列表不包含元素,则返回 true
clear() 从此列表中移除所有元素。
contains(Object o) 如果此列表包含指定的元素,则返回 true
indexOf(Object o) 返回此列表中首次出现的指定元素的索引,如果此列表不包含该元素,则返回 -1。
lastIndexOf(Object o) 返回此列表中最后出现的指定元素的索引,如果此列表不包含该元素,则返回 -1。
toArray() 以正确的顺序(从第一个到最后一个元素)返回一个包含此列表中所有元素的数组。

ArrayList 的遍历方式

遍历是操作集合最频繁的操作之一,主要有四种方式。

ArrayList<String> fruits = new ArrayList<>(List.of("Apple", "Banana", "Cherry"));
// 1. for 循环(通过索引遍历)
// 最传统的方式,适用于需要知道索引的场景
System.out.println("--- For Loop ---");
for (int i = 0; i < fruits.size(); i++) {
    System.out.println(fruits.get(i));
}
// 2. 增强 for 循环 (for-each)
// 最简洁、最推荐的方式,适用于简单遍历
System.out.println("\n--- Enhanced For Loop ---");
for (String fruit : fruits) {
    System.out.println(fruit);
}
// 3. 使用 Iterator (迭代器)
// 适用于在遍历过程中需要安全地删除元素的场景
System.out.println("\n--- Iterator ---");
Iterator<String> iterator = fruits.iterator();
while (iterator.hasNext()) {
    String fruit = iterator.next();
    // 使用 iterator.remove() 来删除当前元素,而不是 list.remove()
    // if ("Banana".equals(fruit)) {
    //     iterator.remove();
    // }
    System.out.println(fruit);
}
// 4. 使用 Java 8+ 的 Stream API
// 非常强大,支持链式操作和并行处理
System.out.println("\n--- Stream API ---");
fruits.stream().forEach(System.out::println);

ArrayList 的注意事项

1 线程安全性

ArrayList 不是线程安全 的,如果在多线程环境下对同一个 ArrayList 实例进行并发修改,可能会导致数据不一致或 ConcurrentModificationException 异常。

解决方案

  • 如果需要线程安全的 List,可以使用 Collections.synchronizedList(new ArrayList<>())
  • 更推荐使用 java.util.concurrent.CopyOnWriteArrayList,它专为并发场景设计。
// 方式1: 使用 Collections 工具类
List<String> syncList = Collections.synchronizedList(new ArrayList<>());
// 方式2: 使用 CopyOnWriteArrayList
List<String> cowList = new CopyOnWriteArrayList<>();

2 泛型

强烈建议在创建 ArrayList 时使用泛型,这样可以:

  • 类型安全:编译器会检查你存入的元素类型是否正确。
  • 避免强制类型转换:从 get() 方法获取元素时,不需要手动强制转换。
// 好的实践
ArrayList<String> list = new ArrayList<>();
list.add("Hello");
String s = list.get(0); // 无需强制转换
// 不好的实践(不使用泛型)
ArrayList rawList = new ArrayList();
rawList.add("Hello");
rawList.add(123); // 编译器不会报错,但非常危险
String s1 = (String) rawList.get(0); // 需要强制转换
String s2 = (String) rawList.get(1); // 运行时抛出 ClassCastException

3 null

ArrayList 可以存储 null 值,但在使用 remove(Object o) 方法时要注意,它会移除第一个匹配的 null

ArrayList<String> list = new ArrayList<>();
list.add("A");
list.add(null);
list.add("B");
list.add(null);
list.remove(null); // 移除第一个 null
// list 现在是: ["A", "B", null]

实战示例

下面是一个综合示例,演示了如何创建、添加、遍历、修改和删除一个 ArrayList

import java.util.ArrayList;
import java.util.Iterator;
public class ArrayListDemo {
    public static void main(String[] args) {
        // 1. 创建一个 ArrayList 来存储学生对象
        ArrayList<Student> studentList = new ArrayList<>();
        // 2. 添加学生
        studentList.add(new Student("张三", 20));
        studentList.add(new Student("李四", 22));
        studentList.add(new Student("王五", 21));
        // 3. 遍历并打印所有学生信息
        System.out.println("--- 初始学生列表 ---");
        for (Student student : studentList) {
            System.out.println(student);
        }
        // 4. 在指定位置插入学生
        studentList.add(1, new Student("赵六", 19));
        System.out.println("\n--- 插入学生后 ---");
        studentList.forEach(System.out::println);
        // 5. 修改学生信息
        studentList.get(0).setAge(21);
        System.out.println("\n--- 修改张三年龄后 ---");
        System.out.println(studentList.get(0));
        // 6. 删除学生
        studentList.remove("王五"); // 注意:需要 Student 类重写 equals 方法
        System.out.println("\n--- 删除王五后 ---");
        Iterator<Student> iterator = studentList.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
        // 7. 获取列表大小
        System.out.println("\n--- 最终列表大小 ---");
        System.out.println("学生总数: " + studentList.size());
    }
}
// 一个简单的 Student 类
class Student {
    private String name;
    private int age;
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Student{" + "name='" + name + '\'' + ", age=" + age + '}';
    }
    // 重写 equals 方法,以便可以通过 remove(Object o) 删除
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age && name.equals(student.name);
    }
}

ArrayList 是 Java 开发中必须掌握的工具,它的核心优势在于动态大小随机访问的快速性,记住它的主要特点、常用方法和注意事项,特别是线程不安全泛型的使用,你就能在日常开发中灵活、高效地运用它。

分享:
扫描分享到社交APP
上一篇
下一篇