Java 教程:深入理解 List 接口

欢迎来到这篇 Java 教程!在 Java 开发中,处理一组对象是至关重要的任务。Java 集合框架(Collections Framework)为此提供了一套强大的工具,而 List 接口是其中最核心、最常用的部分之一。

本文将带你深入了解 List 接口,以及它最常见的两个实现类:ArrayListLinkedList

什么是 List 接口?

在 Java 中,List 是一个接口(java.util.List),它继承自 Collection 接口。List 代表一个有序的集合,它允许我们存储重复的元素。

List 接口的主要特点包括:

  • 有序性List 中的元素是按照插入顺序存储的,你可以精确地控制每个元素在列表中的位置。
  • 允许重复:与 Set 不同,List 允许包含重复的元素。
  • 基于索引的访问List 提供了通过整数索引(位置)来访问元素的方法,如 get(int index)set(int index, E element) 等。

常用的 List 实现类

List 只是一个接口(规范),我们需要使用它的具体实现类来创建对象。最常用的两个实现类是 ArrayListLinkedList

1. ArrayList (动态数组)

ArrayListList 接口最常见的实现,它内部是基于动态数组(Array)来实现的。

  • 特性:查询速度快,因为数组支持通过索引快速访问(O(1) 时间复杂度)。但是,在列表中间插入或删除元素较慢,因为它需要移动后续所有元素(O(n) 时间复杂度)。
  • 适用场景:当你需要频繁地读取和访问元素,而插入和删除操作相对较少时,ArrayList 是最佳选择。

代码示例:

// 导入 List 和 ArrayList
import java.util.List;
import java.util.ArrayList;

public class ArrayListExample {
    public static void main(String[] args) {
        // 创建一个 ArrayList 实例
        List<String> fruits = new ArrayList<>();

        // 1. 添加元素
        fruits.add("苹果");
        fruits.add("香蕉");
        fruits.add("橘子");
        System.out.println("列表内容: " + fruits);

        // 2. 访问元素 (通过索引)
        String firstFruit = fruits.get(0);
        System.out.println("第一个水果: " + firstFruit);

        // 3. 删除元素 (通过索引)
        fruits.remove(1); // 删除 "香蕉"
        System.out.println("删除后: " + fruits);

        // 4. 检查大小
        System.out.println("列表大小: " + fruits.size());
    }
}
2. LinkedList (链表)LinkedList 内部是基于双向链表(Doubly-Linked List)来实现的。特性:在列表中间插入或删除元素非常快(O(1) 时间复杂度),因为它只需要改变前后节点的指针。但是,查询和访问元素(get(int index))较慢,因为它需要从头或尾开始遍历链表(O(n) 时间复杂度)。适用场景:当你需要频繁地在列表开头、结尾或中间进行插入和删除操作时,LinkedList 更合适。代码示例:Java// 导入 List 和 LinkedList
import java.util.List;
import java.util.LinkedList;

public class LinkedListExample {
    public static void main(String[] args) {
        // 创建一个 LinkedList 实例
        List<String> animals = new LinkedList<>();

        // 1. 添加元素
        animals.add("狗");
        animals.add("猫");
        animals.add("鸟");

        // 2. 在开头添加 (LinkedList 特有方法,但 List 接口通过 add(index, E) 也支持)
        ((LinkedList<String>) animals).addFirst("老鼠");
        System.out.println("列表内容: " + animals);

        // 3. 删除最后一个
        ((LinkedList<String>) animals).removeLast();
        System.out.println("删除后: " + animals);
    }
}
ArrayList vs. LinkedList选择 ArrayList 还是 LinkedList 是面试中常见的问题。关键在于理解它们底层的数据结构差异。这里是一个简单的对比表格:特性ArrayList (动态数组)LinkedList (双向链表)底层结构动态数组双向链表随机访问 (Get)快 (O(1))慢 (O(n))插入 (Add)结尾快 (O(1)),中间慢 (O(n))快 (O(1)) (如果已有迭代器)删除 (Remove)结尾快 (O(1)),中间慢 (O(n))快 (O(1)) (如果已有迭代器)内存占用较少(只需要数组本身)较大(每个节点都需额外存储前后指针)如何遍历 List遍历 List 是最常见的操作。推荐使用 for-each 循环。1. 使用 for-each 循环 (推荐)这是最简洁、最易读的方式。JavaList<String> names = new ArrayList<>();
names.add("张三");
names.add("李四");
names.add("王五");

for (String name : names) {
    System.out.println(name);
}
2. 使用迭代器 (Iterator)当需要在遍历时安全地删除元素时,必须使用迭代器。Javaimport java.util.Iterator;

// ... (省略 names 列表的创建)

Iterator<String> iterator = names.iterator();
while (iterator.hasNext()) {
    String name = iterator.next();
    if (name.equals("李四")) {
        iterator.remove(); // 安全删除
    }
}
System.out.println("删除“李四”后: " + names);
总结List 接口是 Java 集合框架的基石。在 ArrayList 和 LinkedList 之间选择时,请记住这个简单的原则:默认使用 ArrayList:它在大多数情况下性能都很好,特别是查询和遍历操作。仅在 ArrayList 成为性能瓶颈时(例如,你确定需要在一个巨大列表的中间进行成千上万次插入/删除),才考虑使用 LinkedList。希望这篇教程能帮助你打好 Java 集合的基础!

Java 教程:深入理解 List 接口
http://example.com/2025/11/10/java/
作者
John Doe
发布于
2025年11月10日
许可协议