杰瑞科技汇

Java List循环遍历有哪些高效方式?

我们将以一个 List<String> 为例进行演示:

Java List循环遍历有哪些高效方式?-图1
(图片来源网络,侵删)
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class ListIterationExample {
    public static void main(String[] args) {
        List<String> fruits = new ArrayList<>(Arrays.asList("Apple", "Banana", "Cherry", "Date"));
        // 我们将使用不同的方法遍历这个 fruits 列表
    }
}

传统的 For 循环 (索引遍历)

这是最基础、最通用的遍历方式,适用于任何实现了 List 接口的集合。

特点:

  • 通过索引(从 0 开始)来访问每个元素。
  • 可以在遍历过程中方便地获取元素的索引。
  • 如果需要在遍历时修改列表(例如删除元素),必须非常小心,否则容易抛出 IndexOutOfBoundsException 或导致逻辑错误。
// fruits 列表: ["Apple", "Banana", "Cherry", "Date"]
System.out.println("--- 1. For 循环 (索引遍历) ---");
for (int i = 0; i < fruits.size(); i++) {
    String fruit = fruits.get(i);
    System.out.println("索引 " + i + ": " + fruit);
}
// 输出:
// 索引 0: Apple
// 索引 1: Banana
// 索引 2: Cherry
// 索引 3: Date

适用场景:

  • 当你需要元素的索引时。
  • 遍历数组时(数组没有 forEach 方法)。
  • 在某些旧版 Java 项目中。

增强 For 循环 (For-Each 循环)

这是 Java 5 引入的一种更简洁、更安全的遍历方式。

Java List循环遍历有哪些高效方式?-图2
(图片来源网络,侵删)

特点:

  • 语法简洁,可读性高。
  • 底层使用迭代器实现,可以避免索引越界的问题。
  • 重要: 在使用增强 for 循环遍历集合时,不能直接修改集合的结构(如 add()remove()),否则会抛出 ConcurrentModificationException,如果需要修改,应使用迭代器的 remove() 方法。
// fruits 列表: ["Apple", "Banana", "Cherry", "Date"]
System.out.println("\n--- 2. 增强 For 循环 (For-Each) ---");
for (String fruit : fruits) {
    System.out.println("水果: " + fruit);
}
// 输出:
// 水果: Apple
// 水果: Banana
// 水果: Cherry
// 水果: Date

适用场景:

  • 这是最常用、最推荐的遍历方式,当只需要集合中的元素,而不需要索引时。
  • 代码简洁,不易出错。

使用迭代器 (Iterator)

迭代器是 Java 集合框架的一部分,它提供了一种标准的方式来遍历集合,并且可以在遍历时安全地修改集合。

特点:

Java List循环遍历有哪些高效方式?-图3
(图片来源网络,侵删)
  • hasNext():检查是否还有下一个元素。
  • next():获取下一个元素。
  • remove()移除最近由 next() 返回的元素,这是在遍历时安全删除元素的标准方法。
// fruits 列表: ["Apple", "Banana", "Cherry", "Date"]
System.out.println("\n--- 3. 使用迭代器 (Iterator) ---");
Iterator<String> iterator = fruits.iterator();
while (iterator.hasNext()) {
    String fruit = iterator.next();
    System.out.println("水果: " + fruit);
    // 示例:移除 "Banana"
    if ("Banana".equals(fruit)) {
        iterator.remove(); // 安全地移除元素
    }
}
System.out.println("移除 Banana 后的列表: " + fruits);
// 输出:
// 水果: Apple
// 水果: Banana
// 水果: Cherry
// 水果: Date
// 移除 Banana 后的列表: [Apple, Cherry, Date]

适用场景:

  • 当你需要在遍历过程中添加、删除或修改集合中的元素时。
  • 这是唯一一种可以在遍历时安全地修改集合结构的方式。

Java 8+ Stream API (流式处理)

这是 Java 8 引入的函数式编程特性,它提供了一种强大而灵活的方式来处理集合。

特点:

  • 声明式:你只需告诉“做什么”,而不需要关心“怎么做”。
  • 惰性求值:很多中间操作(如 filter, map)不会立即执行,只有遇到终端操作(如 forEach, collect)时才会触发。
  • 并行处理:可以轻松地切换到并行流,利用多核 CPU 提高处理速度。
// fruits 列表: ["Apple", "Banana", "Cherry", "Date"]
System.out.println("\n--- 4. 使用 Stream API ---");
// 4.1 forEach 遍历
System.out.println("--- 4.1 Stream.forEach ---");
fruits.stream().forEach(fruit -> System.out.println("水果: " + fruit));
// 4.2 结合 filter 和 forEach 进行条件遍历
System.out.println("\n--- 4.2 Stream.filter + forEach ---");
fruits.stream()
      .filter(fruit -> fruit.startsWith("A")) // 筛选出以 "A" 开头的水果
      .forEach(fruit -> System.out.println("以 A 开头的水果: " + fruit));
// 输出:
// 水果: Apple
// 水果: Banana
// 水果: Cherry
// 水果: Date
// 
// 以 A 开头的水果: Apple

适用场景:

  • 当你需要对集合元素进行复杂的转换、过滤、聚合等操作时。
  • 当你希望代码更具可读性和声明性时。
  • 当你需要利用并行处理来提升性能时。

Java 8+ forEach 和方法引用

这是 Stream API 的一个简化写法,当你的操作非常简单时(比如只是打印),可以使用方法引用让代码更简洁。

// fruits 列表: ["Apple", "Banana", "Cherry", "Date"]
System.out.println("\n--- 5. forEach 和方法引用 ---");
fruits.forEach(System.out::println);
// 输出:
// Apple
// Banana
// Cherry
// Date

适用场景:

  • 当你对每个元素执行的操作非常简单,且该操作恰好是某个已存在方法时(如 System.out.println)。
  • 代码极度简洁,可读性极高。

总结与最佳实践

方法 语法 是否可修改集合 获取索引 可读性 主要适用场景
传统 For 循环 for (int i=0; i<list.size(); i++) (需谨慎) 一般 需要索引;遍历数组
增强 For 循环 for (T item : list) 最常用,仅需元素
迭代器 while (it.hasNext()) (安全) 中等 遍历中需修改集合
Stream API list.stream().forEach(...) (复杂操作时) 函数式操作、过滤、转换、并行
方法引用 list.forEach(System.out::println) 极高 简单的、无副作用的操作

如何选择?

  1. 只需要遍历元素,不需要索引,也不需要修改集合

    • 首选 增强 for 循环,它简单、直观、高效。
    • 如果操作非常简单(如打印),可以考虑 forEach + 方法引用
  2. 需要在遍历过程中修改集合(如删除元素)

    • 必须使用 迭代器,这是唯一安全的方式。
  3. 需要对集合进行复杂的操作(如过滤、转换、聚合、排序)

    • 首选 Stream API,它能让你的代码更清晰、更强大,并易于并行化。
  4. 需要获取元素的索引

    • 使用 传统 For 循环,虽然 Java 8 的 IntStream 也可以实现,但传统循环在这种情况下更直接。

现代 Java 开发建议:

  • 优先使用 增强 for 循环Stream API
  • 避免在增强 for 循环中直接调用 list.remove()
  • 迭代器 专门用于需要修改集合结构的场景。
分享:
扫描分享到社交APP
上一篇
下一篇