Java Stream 流篇 —— 函数链式编程

1. 什么是 Stream 流?

StreamJava 8 引入的全新集合处理方式,旨在用 函数式编程 的思想处理数据,极大减少了代码量和复杂度。
它不是集合,也不存储数据,而是基于数据源(如集合、数组、I/O)进行 声明式、链式操作

关键理念:数据源 → 一系列中间操作(加工、过滤) → 终止操作(收集、输出、聚合)


2. 为什么叫“链式编程”?

传统写法通常需要 循环+条件+中间变量,Stream 则通过方法链连续调用,每一步返回新的 Stream 对象,最终以一个终止方法结束。例子对比:

// 传统写法
List<String> list = Arrays.asList("apple", "banana", "pear", "orange");
List<String> result = new ArrayList<>();
for (String s : list) {
    if (s.length() > 5) {
        result.add(s.toUpperCase());
    }
}
System.out.println(result);

// Stream 链式写法
List<String> result2 = list.stream()
    .filter(s -> s.length() > 5)  // 过滤
    .map(String::toUpperCase)     // 转大写
    .toList();                    // 收集结果
System.out.println(result2);

3. Stream 链式编程核心结构

一个完整的链式编程通常包含 三步

  1. 获取流(创建数据流)

  2. 中间操作(加工、转换,可多个)

  3. 终止操作(触发执行)

dataSource.stream()   // 1. 获取流
    .filter(...)      // 2. 中间操作
    .map(...)         // 2. 中间操作
    .sorted(...)      // 2. 中间操作
    .collect(...);    // 3. 终止操作


4. 常见中间操作(Intermediate Operations)

中间操作是惰性求值,不会立即执行,直到遇到终止操作。

方法作用示例
filter(Predicate)过滤.filter(x -> x > 5)
map(Function)数据转换.map(String::length)
flatMap(Function)扁平化流.flatMap(List::stream)
distinct()去重.distinct()
sorted() / sorted(Comparator)排序.sorted(Comparator.reverseOrder())
limit(n)截取前 n 个.limit(3)
skip(n)跳过前 n 个.skip(2)
peek(Consumer)调试/查看中间值.peek(System.out::println)


5. 常见终止操作(Terminal Operations)

终止操作会触发流的执行,并产生结果或副作用。

方法作用示例
collect(Collector)收集结果.collect(Collectors.toList())
toList()收集到 List(Java 16+).toList()
forEach(Consumer)遍历.forEach(System.out::println)
count()计数.count()
reduce()聚合计算.reduce(0, Integer::sum)
min() / max()最小/最大值.max(Integer::compareTo)
anyMatch() / allMatch() / noneMatch()条件匹配.anyMatch(x -> x > 10)
findFirst() / findAny()获取元素.findFirst().orElse(null)


6. 链式编程案例

案例 1:员工工资处理

import java.util.*;
import java.util.stream.*;

class Employee {
    String name;
    double salary;
    public Employee(String name, double salary) {
        this.name = name;
        this.salary = salary;
    }
    public String getName() { return name; }
    public double getSalary() { return salary; }
}

public class StreamDemo {
    public static void main(String[] args) {
        List<Employee> employees = Arrays.asList(
            new Employee("Tom", 5000),
            new Employee("Jerry", 7000),
            new Employee("Lily", 9000),
            new Employee("Lucy", 12000)
        );

        List<String> highSalaryNames = employees.stream()
            .filter(e -> e.getSalary() > 8000)     // 工资 > 8000
            .sorted(Comparator.comparing(Employee::getSalary).reversed()) // 按工资降序
            .map(Employee::getName)               // 提取姓名
            .toList();                             // 收集结果

        System.out.println(highSalaryNames); // [Lucy, Lily]
    }
}


案例 2:单词去重统计

List<String> words = Arrays.asList("apple", "banana", "apple", "orange", "banana");

long count = words.stream()
    .distinct()    // 去重
    .count();      // 统计数量

System.out.println(count); // 3


7. 链式编程的优点

  • 简洁:减少样板代码

  • 可读性高:逻辑步骤清晰

  • 可组合性:中间操作可随意组合

  • 并行化支持:可直接 .parallelStream() 提升性能


8. 注意事项

  1. Stream 只能使用一次,用完就要重新获取。

  2. 中间操作是惰性执行的,没有终止操作不会触发。

  3. 并行流虽然能提升性能,但在小数据量或线程不安全场景可能反而更慢。

  4. .peek() 适合调试,生产代码不要依赖它改变数据。


总结
Java Stream 的链式编程,本质上是函数式编程 + 方法链调用,让你能用声明式的方式处理集合数据,代码更简洁、逻辑更清晰、可读性更高。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星空下的DeppBing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值