1. 什么是 Stream?

Stream 是 Java 8+ 处理集合数据的声明式工具。它不存储数据,而是像流水线一样对数据进行过滤、转换和聚合。

核心特点:懒加载(只有执行终端操作时才开始计算)、函数式编程风格。

2. 核心用法速查

2.1 创建流

List list = Arrays.asList("a", "b", "c");

// 从集合创建
Stream stream1 = list.stream();

// 从数组创建
Stream stream2 = Arrays.stream(new Integer[]{1, 2, 3});

// 静态创建
Stream stream3 = Stream.of("x", "y", "z");

2.2 中间操作(可链式调用,不立即执行)

方法 作用 示例
filter 过滤 .filter(s -> s.length() > 1)
map 转换元素 .map(String::toUpperCase)
sorted 排序 .sorted().sorted(Comparator.reverseOrder())
distinct 去重 .distinct()
limit 截取前N个 .limit(5)
skip 跳过前N个 .skip(2)

2.3 终端操作(触发执行,返回结果)

方法 作用 返回值
collect 收集结果 List, Set, Map
forEach 遍历消费 void
count 统计数量 long
anyMatch 是否存在匹配 boolean
findFirst 获取第一个 Optional<T>
reduce 归约计算 Optional<T>T

3. 实战代码示例

3.1 场景一:过滤 + 转换 + 收集

List result = list.stream()
    .filter(s -> s.startsWith("a"))      // 过滤以'a'开头
    .map(String::toUpperCase)            // 转大写
    .collect(Collectors.toList());       // 收集为List

3.2 场景二:分组统计

// 按长度分组
Map> grouped = list.stream()
    .collect(Collectors.groupingBy(String::length));

// 统计每个分组的数量
Map countMap = list.stream()
    .collect(Collectors.groupingBy(String::length, Collectors.counting()));

3.3 场景三:数值计算

List nums = Arrays.asList(1, 2, 3, 4, 5);

// 求和
int sum = nums.stream().mapToInt(Integer::intValue).sum();

// 求最大值
OptionalInt max = nums.stream().mapToInt(Integer::intValue).max();

3.4 场景四:去重与排序

List uniqueSorted = nums.stream()
    .distinct()           // 去重
    .sorted(Comparator.reverseOrder()) // 降序
    .collect(Collectors.toList());

4. 避坑小贴士

  1. 不要修改外部变量:Stream 内部严禁修改外部集合或变量(线程不安全)。
    • ❌ 错误:stream.forEach(list::add)
    • ✅ 正确:stream.collect(Collectors.toList())
  2. 慎用 parallelStream:仅在数据量极大且无 IO 阻塞时使用,否则可能比串行更慢。
  3. 注意 NullPointerException:流中元素为 null 时,mapfilter 可能报错,建议先 filter(Objects::nonNull)
  4. toList() vs collect:Java 16+ 可直接用 .toList() 返回不可变列表,更简洁。

5. 总结

  • 简单处理stream().filter().map().collect()
  • 复杂统计Collectors.groupingBy() / summarizingInt()
  • 性能优先:小数据用串行,大数据且纯计算用并行,涉及 IO 坚决不用并行。
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐