在Java中如何使用for-each循环遍历集合_Java增强型循环遍历解析

for-each能遍历数组(含基本类型)和实现了Iterable接口的类(如ArrayList、HashSet等);Map本身不可遍历,需用entrySet()、keySet()或values();遍历时修改集合会抛ConcurrentModificationException。

Java中的

for-each循环(增强型for)只能用于实现了Iterable接口的集合或数组,不能直接遍历Map本身,也不能在遍历时安全地删除元素。

for-each能遍历哪些类型?

它底层调用的是Iterator,因此要求目标必须满足以下任一条件:

  • 是数组(任何类型,包括基本类型数组)
  • 是实现了Iterable接口的类,如ArrayListHashSetLinkedListLinkedHashMap
  • 自定义类显式实现Iterable并提供iterator()方法

常见误用:Map不是Iterable,所以for (Entry e : map)会编译失败;必须用map.entrySet()map.keySet()map.values()之一。

遍历Map时的三种正确写法

因为Map本身不支持for-each,但它的三个视图都实现了Iterable

Map map = new HashMap<>();
map.put("a", 1);
map.put("b", 2);

// ✅ 遍历键值对
for (Map.Entry entry : map.entrySet()) {
    System.out.println(entry.getKey() + "=" + entry.getValue());
}

// ✅ 遍历键
for (String key : map.keySet()) {
    System.out.println("key: " + key);
}

// ✅ 遍历值
for (Integer value : map.values()) {
    System.out.println("value: " + value);
}

注意:entrySet()返回的是Set>,不是List,所以顺序不保证(除非用LinkedHashMap)。

for-each中修改集合会抛ConcurrentModificationException

这是最容易踩的坑:在for-each循环体内调用list.remove()set.add()等结构性修改操作,会导致运行时异常。

  • 原因:for-each隐式使用Iterator,而其checkForComodification()机制会检测modCount变化
  • 替代方案:显式使用Iterator并调用iterator.remove()
  • 若需添加元素,必须跳出循环后操作,或改用传统for索引循环(仅适用于List

错误示例:

List list = new ArrayList<>(Arrays.asList("a", "b", "c"));
for (String s : list) {
    if ("b".equals(s)) {
        list.remove(s); // ⚠️ 抛 ConcurrentModificationException
    }
}

性能与语义限制:什么时候不该用for-each

for-each简洁,但有明确边界:

  • 需要访问当前索引(如“第几个元素”)→ 改用传统for (int i = 0; i
  • 需要并行遍历多个集合 → 只能用索引或Iterator手动控制
  • 遍历过程中要移除多个匹配项 → 用Iterator.remove()更安全清晰
  • 对基本类型数组,for-each无装箱开销,但若需修改原数组元素,则无效(因为遍历的是副本)

例如,想把int[]中每个数翻倍,for (int x : arr) { x *= 2; }完全不会改变arr内容——必须用索引赋值。