java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java for-each循环(遍历循环)

Java for-each循环(遍历循环)详解

作者:晚夜微雨问海棠呀

本文详解Java for-each循环,涵盖其简化遍历、类型安全、不可变性、空指针防护等特性,适用场景及限制,错误案例与修正,性能对比,高级技巧(如Java14 Records),并提供最佳实践指南

一、本质与语法

// 标准语法 (Java 5+)
for (ElementType element : Iterable/Array) {
    // 操作element
}

// 等效传统实现
Iterator<ElementType> it = collection.iterator();
while (it.hasNext()) {
    ElementType element = it.next();
    // 操作element
}

设计目标:简化集合/数组遍历,消除显式迭代器操作

底层机制

二、核心特性

强制类型安全

List<String> list = Arrays.asList("A", "B");
for (Integer num : list) {} // 编译错误:类型不匹配

不可变性保证

for (final String s : list) { 
    s = "new"; // 编译错误:final修饰符
}

空指针防护

for (Object obj : null) { ... } // 运行时抛出NullPointerException

三、适用场景与限制

支持的数据结构不支持的操作场景
所有实现Iterable的集合遍历时删除元素(需用Iterator.remove())
数组需要反向遍历
自定义可迭代对象需要同时访问索引

四、典型错误案例

并发修改异常

List<String> list = new ArrayList<>(Arrays.asList("A", "B"));
for (String s : list) {
    list.remove(s); // 抛出ConcurrentModificationException
}

✅ 修正方案:改用迭代器遍历 + remove()

对象引用陷阱

List<StringBuilder> list = new ArrayList<>();
list.add(new StringBuilder("Hello"));
for (StringBuilder sb : list) {
    sb.append(" World"); // 修改对象内部状态 ✔️
    sb = new StringBuilder(); // 仅改变局部引用 ✖️
}

五、性能对比分析

数据结构for-each传统for循环推荐方案
ArrayList迭代器遍历(稍慢)索引直接访问(快)大数据量选传统式
LinkedList迭代器遍历(快)索引遍历(O(n²))必须用for-each
HashSet唯一安全遍历方式无法直接使用索引强制使用for-each

六、高级应用技巧

多维数组遍历

int[][] matrix = {{1,2}, {3,4}};
for (int[] row : matrix) {
    for (int num : row) {
        System.out.print(num + " ");
    }
}

自定义可迭代对象

class MyIterable implements Iterable<String> {
    public Iterator<String> iterator() {
        return Arrays.asList("A","B").iterator();
    }
}

并行遍历优化(Java 8+)

list.parallelStream().forEach(element -> {
    // 多线程处理(注意线程安全)
});

七、最佳实践指南

优先选择场景

规避风险策略

// 防御性复制(针对可能被修改的集合)
for (String s : new ArrayList<>(originalList)) {
    originalList.remove(s); // 安全操作
}

类型推断优化(Java 10+)

var entries = Map.of(1,"A",2,"B").entrySet();
for (var entry : entries) {
    System.out.println(entry.getKey() + ":" + entry.getValue());
}

深度扩展:Java 14引入的Records类型可与for-each循环完美配合:

record Point(int x, int y) {}
List<Point> points = List.of(new Point(1,2), new Point(3,4));
for (Point(var x, var y) : points) { // 模式匹配解构(Java 17预览特性)
    System.out.println(x + "," + y);
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文