Skip to content
章节导航

内部迭代与外部迭代

考量因素推荐外部迭代推荐内部迭代
代码简洁性❌ 需要更多代码✅ 更简洁
可读性❌ 业务逻辑分散✅ 声明式,更清晰
并行化❌ 困难,需要手动实现✅ 简单,.parallelStream()
性能控制✅ 完全控制,可手动优化❌ 由JVM控制
复杂控制流✅ 灵活(break、continue)❌ 有限制
修改集合✅ 可直接修改❌ 不能修改源集合
异常处理✅ 精细控制❌ 相对困难
函数式风格❌ 命令式✅ 函数式

场景

场景推荐原因
简单遍历外部迭代(for-each)更直接
数据转换内部迭代(Stream)更简洁
并行处理内部迭代(parallelStream)更简单
复杂业务逻辑内部迭代更清晰
性能关键根据情况选择需要测试

内部迭代

遍历将在集合内部进行,我们不会显式地去控制这个循环

java
// 外部迭代(传统方式 - 命令式编程)
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
List<String> result = new ArrayList<>();

// 程序员显式控制迭代过程
for (String name : names) {            // 1. 程序员控制迭代
    if (name.startsWith("A")) {        // 2. 程序员处理业务逻辑
        result.add(name.toUpperCase());
    }
}
// 问题:业务逻辑和迭代逻辑混杂在一起

// 内部迭代(Stream - 声明式编程)
List<String> result = names.stream()   // 获取数据源
    .filter(name -> name.startsWith("A"))  // 做什么(业务逻辑)
    .map(String::toUpperCase)              // 做什么(业务逻辑)
    .collect(Collectors.toList());         // 得到结果
// Stream API 控制迭代过程,程序员只关心业务逻辑



// 不好:多次终端操作
long count = list.stream().filter(condition).count();
List<T> filtered = list.stream().filter(condition).collect(toList());

// 好:一次终端操作
List<T> filtered = list.stream()
    .filter(condition)
    .collect(toList());
long count = filtered.size();

// 不好:昂贵的中间操作
stream.sorted().filter(condition).findFirst();

// 好:先过滤再排序
stream.filter(condition).sorted().findFirst();

外部迭代

外部迭代指程序员直接控制迭代过程,显式地使用循环结构(如 for、while)来遍历集合元素。

java
// 外部迭代的典型形式
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");

// 程序员控制迭代过程
for (int i = 0; i < names.size(); i++) {       // 控制索引
    String name = names.get(i);                // 获取元素
    System.out.println(name);                  // 处理元素
}

// 或使用增强for循环
for (String name : names) {                    // 控制遍历
    System.out.println(name);                  // 处理元素
}

// 或使用迭代器
Iterator<String> iterator = names.iterator();  // 获取迭代器
while (iterator.hasNext()) {                   // 控制迭代
    String name = iterator.next();             // 获取并处理
    System.out.println(name);
}