Java Stream API 入门:像流水线一样处理集合

前面学过 List、Set 这些集合,遍历它们最常见的就是 for 循环。不过 Java 8 之后多了一个更顺手的工具:Stream(流)。它把"筛选、转换、汇总"这些操作串成一条流水线,代码写起来又短又清楚。

什么是 Stream

Stream 不是集合,也不存数据,它只是数据源上的一条"加工流水线":数据从头流进去,经过一道道工序,最后从出口流出来。

用 Stream 一般分三步:

  1. 拿到流:list.stream()
  2. 中间操作:filter(过滤)、map(转换)等,可以串很多道
  3. 结尾操作:collect(收集)、forEach(遍历)、count(计数)等,产出结果

注意:Stream 用一次就没了,想再用要重新 .stream()。

filter:留下满足条件的

import java.util.List;
import java.util.stream.Collectors;

public class Demo {
    public static void main(String[] args) {
        List<Integer> nums = List.of(3, 8, 12, 7, 20, 5);

        List<Integer> big = nums.stream()
                .filter(n -> n >= 10)          // 只留 >= 10 的
                .collect(Collectors.toList()); // 收集成新 List

        System.out.println(big); // 输出: [12, 20]
    }
}

n -> n >= 10 是 Lambda 表达式,意思是"对每一项 n,判断 n >= 10"。filter 只负责过筛子,原集合不会被改动。

map:把每个元素变成另一个样子

List<String> names = List.of("tom", "jerry", "spike");

List<String> upper = names.stream()
        .map(String::toUpperCase)   // 每个名字转大写
        .collect(Collectors.toList());

System.out.println(upper); // 输出: [TOM, JERRY, SPIKE]

map 是一道加工工序:进去一个元素,出来一个新元素。类型也可以顺便变,比如 map(String::length) 把字符串流转成整数流。

串联流水线:filter + map + sorted

多道工序串起来才见威力。比如从一堆名字里挑出长度大于 3 的,转大写,再排序:

List<String> names = List.of("tom", "jerry", "anna", "spike");

List<String> result = names.stream()
        .filter(n -> n.length() > 3)  // jerry, anna, spike
        .map(String::toUpperCase)     // JERRY, ANNA, SPIKE
        .sorted()                     // 排序
        .collect(Collectors.toList());

System.out.println(result); // 输出: [ANNA, JERRY, SPIKE]

读代码时顺着链往下读就行:"过滤 → 转换 → 排序 → 收集",和流水线的意思一模一样。

常用的结尾操作

除了 collect,还有几个一眼能看懂的结尾操作:

List<Integer> nums = List.of(5, 3, 9, 1);

long count = nums.stream().filter(n -> n > 2).count();
System.out.println(count); // 输出: 3

// forEach:挨个处理,没有返回值
nums.stream().sorted().forEach(n -> System.out.print(n + " "));
// 输出: 1 3 5 9

// anyMatch:只要有任意一项满足条件就为 true
boolean hasBig = nums.stream().anyMatch(n -> n > 8);
System.out.println(hasBig); // 输出: true

小结

  • Stream 是集合上的加工流水线:先 stream() 拿流,中间用 filter/map 加工,最后用 collect/forEach 出结果
  • filter 过滤、map 转换、sorted 排序,可以任意串联
  • Stream 不改原集合,而且只能消费一次
  • 数据量不大时性能和 for 循环差不多,胜在代码短、意图清楚

下次处理集合时,不妨试试把三层嵌套的 for 换成一条 Stream 流水线。