Skip to content

Stream API 详解


一、是什么?

Java Stream 是 JDK 8 引入的 API,用于对集合数据进行声明式处理(如过滤、映射、排序)。它不是数据结构,而是对数据源(集合、数组等)进行高效聚合操作的工具,支持链式调用并行处理

二、解决什么问题?

  1. 简化集合操作:替代繁琐的 for 循环,代码更简洁。
  2. 提升可读性:链式调用让数据处理流程一目了然。
  3. 并行优化parallelStream() 自动利用多核 CPU 加速计算。
  4. 延迟执行:中间操作合并后执行,减少迭代次数。

三、核心方法(代码题高频使用)

类型方法作用示例
创建stream()集合转 Streamlist.stream()
Arrays.stream()数组转 StreamArrays.stream(new int[]{1,2})
中间操作filter(Predicate)条件过滤.filter(n -> n > 10)
map(Function)元素转换.map(String::toUpperCase)
sorted()排序(自然序或自定义比较器).sorted(Comparator.reverseOrder())
distinct()去重.distinct()
limit(n)截取前 n 个元素.limit(5)
终止操作collect()转换为集合(如 List/Set).collect(Collectors.toList())
forEach()遍历每个元素.forEach(System.out::println)
count()统计元素数量.count()
reduce()聚合计算(如求和).reduce(0, Integer::sum)

JDK 9+ 新增

  • takeWhile(Predicate):取元素直到条件不满足
  • dropWhile(Predicate):丢弃元素直到条件满足

四、应用场景(代码题常见题型)

  1. 数据过滤

    java
    // 筛选列表中大于 10 的偶数
    List<Integer> result = list.stream()
        .filter(n -> n > 10)
        .filter(n -> n % 2 == 0)
        .collect(Collectors.toList());
  2. 对象集合处理

    java
    // 提取所有学生姓名并转为大写
    List<String> names = students.stream()
        .map(Student::getName)
        .map(String::toUpperCase)
        .collect(Collectors.toList());
  3. 分组与统计

    java
    // 按年龄分组统计人数
    Map<Integer, Long> ageCount = students.stream()
        .collect(Collectors.groupingBy(
            Student::getAge, 
            Collectors.counting()
        ));
  4. 并行计算(大数据量优化)

    java
    // 并行计算平方和
    int sum = list.parallelStream()
        .mapToInt(n -> n * n)
        .sum();
  5. 链式去重排序

    java
    // 去重后按降序排列
    List<Integer> processed = list.stream()
        .distinct()
        .sorted(Comparator.reverseOrder())
        .collect(Collectors.toList());

五、重要注意事项

  1. 流不可复用
    一个 Stream 只能被消费一次,重复操作会抛 IllegalStateException

    java
    Stream<Integer> stream = list.stream();
    stream.count(); // 终止操作
    stream.forEach(...); // 错误!流已关闭
  2. 避免副作用
    不要在 filter/map 中修改外部状态(如全局变量),应保持无状态。

  3. 性能权衡

    • 小数据量优先用 for 循环(Stream 有初始化开销)。
    • 大数据量用 parallelStream()(需线程安全)。
  4. 空指针防护
    使用 Optional 处理可能为 null 的结果:

    java
    Optional<Integer> max = list.stream()
        .max(Comparator.naturalOrder());
    max.ifPresent(System.out::println);

六、总结

  • 核心价值:用声明式语法简化集合操作,提升可读性和并行能力。
  • 代码题高频操作filter(过滤)、map(转换)、collect(收集结果)、sorted(排序)。
  • 适用场景:集合数据过滤/转换/统计、链式多步处理、并行计算。
  • 避坑指南:流不可复用、避免副作用、合理选择并行流。

💡 技巧:在代码题中优先用 Stream 处理集合问题,代码更简洁且易得高分!