杰瑞科技汇

Java遍历List和Map有哪些常用方法?

遍历 List (列表)

假设我们有以下一个 List

Java遍历List和Map有哪些常用方法?-图1
(图片来源网络,侵删)
import java.util.Arrays;
import java.util.List;
public class ListIterationExample {
    public static void main(String[] args) {
        List<String> fruits = Arrays.asList("Apple", "Banana", "Cherry", "Date");
    }
}

方法 1:经典 For 循环 (索引遍历)

这是最传统、最基础的方式,通过索引来访问每个元素。

优点

  • 可以获取元素的索引,方便在循环中进行修改或删除(需注意 ConcurrentModificationException)。
  • 在 Java 8 之前是唯一的高效遍历方式。

缺点

  • 代码略显冗长。
  • 对于 LinkedList 等非随机访问列表,通过索引获取元素的性能较差(get(i) 是 O(n) 操作)。

代码示例

System.out.println("--- 1. For 循环 (索引遍历) ---");
for (int i = 0; i < fruits.size(); i++) {
    String fruit = fruits.get(i);
    System.out.println("索引 " + i + ": " + fruit);
}

方法 2:增强 For 循环 (For-Each 循环)

Java 5 引入的语法糖,是遍历集合和数组最推荐、最简洁的方式。

优点

  • 代码简洁易读。
  • 底层使用迭代器,适用于所有 List 实现(包括 LinkedList),性能稳定。
  • 自动处理了迭代器的 hasNext()next(),不易出错。

缺点

  • 无法获取元素的索引。
  • 如果在遍历过程中需要修改集合(非当前元素),可能会抛出 ConcurrentModificationException

代码示例

System.out.println("\n--- 2. 增强 For 循环 (For-Each) ---");
for (String fruit : fruits) {
    System.out.println("水果: " + fruit);
}

方法 3:使用迭代器 (Iterator)

迭代器是集合框架的一部分,提供了标准的遍历接口。

优点

  • 最安全的遍历方式,特别是在遍历过程中需要删除元素时。
  • iterator.remove() 方法可以在不引发 ConcurrentModificationException 的情况下安全地删除当前元素。

缺点

  • 代码比 For-Each 循环稍显繁琐。

代码示例

System.out.println("\n--- 3. 使用迭代器 (Iterator) ---");
// 遍历
for (Iterator<String> iterator = fruits.iterator(); iterator.hasNext(); ) {
    String fruit = iterator.next();
    System.out.println("水果: " + fruit);
}
// 安全删除元素
// List<String> fruitsToRemove = new ArrayList<>(Arrays.asList("Banana"));
// for (Iterator<String> iterator = fruits.iterator(); iterator.hasNext(); ) {
//     String fruit = iterator.next();
//     if (fruitsToRemove.contains(fruit)) {
//         iterator.remove(); // 安全删除
//     }
// }
// System.out.println("删除后的列表: " + fruits);

方法 4:Java 8+ Stream API (流式处理)

Java 8 引入的 Stream API,功能强大,不仅可以遍历,还能进行复杂的链式操作(如过滤、映射、聚合等)。

优点

  • 代码非常简洁,特别是与 Lambda 表达式结合时。
  • 支持并行处理,易于利用多核 CPU。
  • 将数据操作与数据源(集合)分离,代码更具声明性。

缺点

  • 对于简单的遍历,可能比 For-Each 循环有轻微的性能开销(通常可以忽略不计)。
  • 需要学习 Lambda 表达式和 Stream API 的概念。

代码示例

System.out.println("\n--- 4. Java 8+ Stream API ---");
// 1. 简单遍历
fruits.stream().forEach(fruit -> System.out.println("水果: " + fruit));
// 2. 带过滤的遍历
System.out.println("\n--- 带过滤的遍历 (长度大于5) ---");
fruits.stream()
      .filter(fruit -> fruit.length() > 5) // 过滤条件
      .forEach(fruit -> System.out.println("长水果名: " + fruit));

遍历 Map (映射)

假设我们有以下一个 Map

import java.util.HashMap;
import java.util.Map;
public class MapIterationExample {
    public static void main(String[] args) {
        Map<String, Integer> fruitPrices = new HashMap<>();
        fruitPrices.put("Apple", 10);
        fruitPrices.put("Banana", 5);
        fruitPrices.put("Cherry", 20);
    }
}

方法 1:使用 keySet() 和 For-Each 循环

这是最经典、最常用的方式,先获取所有键的集合,然后遍历键,通过键来获取值。

优点

  • 逻辑清晰,易于理解。
  • 如果只需要键,或者只需要值,这种方式很灵活。

代码示例

System.out.println("--- 1. 使用 keySet() 和 For-Each 循环 ---");
// 遍历键
for (String fruit : fruitPrices.keySet()) {
    System.out.println("水果: " + fruit);
}
// 遍历键值对
for (String fruit : fruitPrices.keySet()) {
    Integer price = fruitPrices.get(fruit);
    System.out.println(fruit + " 的价格是: " + price);
}

方法 2:使用 entrySet() 和 For-Each 循环 (推荐)

这是性能最好、最推荐的方式。entrySet() 返回一个 Set<Map.Entry<K, V>>,其中每个 Map.Entry 对象都包含一个键和对应的值。

优点

  • 性能最高:通过 entrySet 遍历,只需要一次 Map.Entry 的查找,而 keySet 方式需要两次查找(一次找 keySet,一次用 keyvalue)。
  • 代码更简洁,直接操作键值对。

缺点

  • 如果只需要键或只需要值,它不如 keySetvalues() 那样直接。

代码示例

System.out.println("\n--- 2. 使用 entrySet() 和 For-Each 循环 (推荐) ---");
for (Map.Entry<String, Integer> entry : fruitPrices.entrySet()) {
    String fruit = entry.getKey();
    Integer price = entry.getValue();
    System.out.println(fruit + " 的价格是: " + price);
}

方法 3:使用 forEach 方法 (Java 8+)

Java 8 为 Map 接口添加了 forEach 方法,接受一个 BiConsumer(二元消费者)函数,使得遍历代码非常简洁。

优点

  • 代码极其简洁,一行搞定。
  • 内部实现通常是基于 entrySet,性能同样很高。

缺点

  • 需要理解 Lambda 表达式。

代码示例

System.out.println("\n--- 3. 使用 Map.forEach() (Java 8+) ---");
fruitPrices.forEach((fruit, price) -> System.out.println(fruit + " 的价格是: " + price));

方法 4:使用迭代器 (Iterator)

List 类似,也可以使用迭代器来遍历 keySetentrySet,这在需要安全删除元素时很有用。

代码示例

System.out.println("\n--- 4. 使用迭代器 (Iterator) ---");
Iterator<Map.Entry<String, Integer>> iterator = fruitPrices.entrySet().iterator();
while (iterator.hasNext()) {
    Map.Entry<String, Integer> entry = iterator.next();
    // 示例:删除价格小于10的水果
    if (entry.getValue() < 10) {
        iterator.remove(); // 安全删除
    }
}
System.out.println("删除后的 Map: " + fruitPrices);

总结与推荐

数据结构 推荐方式 理由
List 增强 For 循环 (For-Each) 代码简洁、易读、性能稳定,适用于 99% 的场景。
Java 8+ Stream API 当需要进行复杂的链式操作(如 filter, map, reduce)时使用。
Map entrySet() + For-Each 性能最高,代码清晰,是遍历 Map 的黄金标准。
Map.forEach() (Java 8+) 代码最简洁,一行搞定,性能与 entrySet 相当,是现代 Java 的首选。

核心建议

  1. 遍历 List:优先使用 For-Each 循环
  2. 遍历 Map:优先使用 entrySet() + For-EachMap.forEach()
  3. 如果只是简单地打印或处理每个元素,For-Each 和 forEach 是最佳选择。
  4. 如果在遍历过程中需要删除元素,请务必使用 迭代器remove() 方法,或者使用 Java 8+ 的 removeIf 方法。
  5. 如果需要对数据进行转换、过滤、聚合等复杂操作,请使用 Stream API
分享:
扫描分享到社交APP
上一篇
下一篇