Stream API
常见的 Java 8 Stream API 可以分成几类:创建、转换、中间操作、终止操作。
-
创建操作 :得到一个流对象
-
中间操作 :返回的还是一个新的流(lazy,不会真正执行)
-
终止操作 :才会触发整个流水线的执行,产生结果(数值、集合、Optional 等)
Stream<Integer> s = Stream.of(1, 2, 3, 4)
.filter(x -> x > 2) // 中间操作,返回流
.map(x -> x * 10); // 中间操作,返回流
// 到这里还没执行,s 只是描述了一条“流水线”
List<Integer> list = s.collect(Collectors.toList()); // 终止操作,真正执行
System.out.println(list); // [30, 40]一、Stream 创建方式
| 方法 | 说明 | 示例 |
|---|---|---|
| Stream.of(T...) | 由一组元素创建 | Stream.of(1,2,3) |
| Arrays.stream(array) | 由数组创建 | Arrays.stream(new int[]{1,2,3}) |
| Collection.stream() | 由集合创建 | list.stream() |
| Collection.parallelStream() | 并行流 | list.parallelStream() |
| Stream.iterate(seed, f) | 无限流(迭代生成) | Stream.iterate(1, n -> n+1) |
| Stream.generate(Supplier) | 无限流(供应生成) | Stream.generate(Math::random) |
二、中间操作(返回新的 Stream,可链式调用)
| 方法 | 说明 | 示例 |
|---|---|---|
| filter(Predicate) | 过滤元素 | stream.filter(x -> x > 10) |
| map(Function) | 映射/转换 | stream.map(String::length) |
| flatMap(Function) | 扁平化映射 | stream.flatMap(s -> Arrays.stream(s.split(","))) |
| distinct() | 去重 | stream.distinct() |
| sorted() | 自然排序 | stream.sorted() |
| sorted(Comparator) | 自定义排序 | stream.sorted((a,b)->b-a) |
| limit(n) | 截取前 n 个 | stream.limit(5) |
| skip(n) | 跳过前 n 个 | stream.skip(3) |
| peek(Consumer) | 调试/查看中间值 | stream.peek(System.out::println) |
三、终止操作(触发流处理,返回具体结果)
-
集合结果 :
collect -
聚合结果 :
reduce、count、min、max -
布尔判断 :
anyMatch、allMatch、noneMatch -
单元素 :
findFirst、findAny -
遍历/副作用 :
forEach
| 方法 | 说明 | 返回值类型 | 示例 |
|---|---|---|---|
| forEach(Consumer) | 遍历元素(无返回) | void | stream.forEach(System.out::println) |
| toArray() | 转数组 | Object[] 或 T[] | stream.toArray() |
| collect(Collector) | 收集结果 | 泛型 R(常见:List、Set、Map) | stream.collect(Collectors.toList()) |
| reduce(BinaryOperator) | 规约(累加、累乘等) | Optional |
stream.reduce(Integer::sum) |
| reduce(identity, BinaryOperator) | 带初始值的规约 | T | stream.reduce(0, Integer::sum) |
| count() | 统计数量 | long | stream.count() |
| min(Comparator) | 最小值 | Optional |
stream.min(Integer::compare) |
| max(Comparator) | 最大值 | Optional |
stream.max(Integer::compare) |
| anyMatch(Predicate) | 是否存在任意满足条件 | boolean | stream.anyMatch(x -> x > 10) |
| allMatch(Predicate) | 是否所有元素满足条件 | boolean | stream.allMatch(x -> x > 0) |
| noneMatch(Predicate) | 是否没有元素满足条件 | boolean | stream.noneMatch(x -> x < 0) |
| findFirst() | 返回第一个元素 | Optional |
stream.findFirst() |
| findAny() | 返回任意一个元素(并行流常用) | Optional |
stream.findAny() |
Optional 类
Optional<T> 是一个可能包含值也可能为空的容器对象,它替代了传统的 null 返回,用更安全、明确、链式的方式 处理值的存在或缺失。
常用方法如下所示:
| 方法名 | 返回值 | 说明 |
|---|---|---|
| of(T value) | Optional |
创建非空的 Optional,传 null 会抛异常 |
| ofNullable(T value) | Optional |
创建 Optional,允许 null |
| empty() | Optional |
创建一个空的 Optional |
| isPresent() | boolean | 判断是否有值(true/false) |
| ifPresent(Consumer) | void | 如果有值就执行某个操作 |
| get() | T | 获取值,若为空会抛 NoSuchElementException |
| orElse(T other) | T | 若有值则返回,否则返回默认值**(总会执行传入的表达式,无论是否为空)** |
| orElseGet(Supplier) | T | 若有值返回,否则调用函数获取默认值**(只有为空才会执行传入的表达式)** |
| orElseThrow() | T | 若为空抛异常(默认抛 NoSuchElementException) |
| orElseThrow(Supplier) | T | 若为空抛自定义异常 |
| map(Function) | Optional |
对值做转换操作(包装成新的 Optional) |
| flatMap(Function) | Optional |
链式调用,避免嵌套 Optional |
| filter(Predicate) | Optional |
判断值是否满足条件,不满足则变成 empty |
注意事项:
-
❌ 不要用
get()随意取值 ,如果值为 null 会直接抛异常。 -
✅ 推荐始终使用
orElse/ifPresent等方法来处理 Optional。
// 创建一个optional对象
Optional<String> optionalName = Optional.of("lirendada");
// 1. 是否有值
optionalName.isPresent(); // true
// 2. 如果有值就打印
optionalName.ifPresent(name -> System.out.println("Name: " + name));
// 3. 获取值(不推荐直接用 get)
String name = optionalName.get();
// 4. 如果为空则返回默认值
String value = Optional.ofNullable(null).orElse("默认值"); // "默认值"
// 5. 用 orElseGet 延迟执行
String v = Optional.ofNullable(null).orElseGet(() -> getDefault());
// 6. 为空则抛异常
String error = Optional.ofNullable(null)
.orElseThrow(() -> new IllegalArgumentException("值不能为空"));
// 7. 转换值(map)
Optional<Integer> nameLength = optionalName.map(String::length);
// 8. 链式调用 + 判断
String result = Optional.of("lirendada")
.filter(s -> s.length() > 5)
.map(String::toUpperCase)
.orElse("太短了");
// 输出:LIRENDADA两者结合的一个例子
findFirst() 是 Java Stream 中的一个终止操作(Terminal Operation) ,作用是:
在过滤或处理后的流中,返回“第一个匹配的元素”(包装在
Optional中)。
如果不用 findFirst() 结束的话,就会得到一个 无限的 Stream 流对象 ,而不是最终的 PrizeEntity 元素。
Optional<PrizeEntity> optionalPrizeDTO = prizes.stream()
.filter(y -> y.getId().equals(x.getPrizeId()))
.findFirst();
// 如果 optionalPrizeDTO 不为空,执行该方法
optionalPrizeDTO.ifPresent(y -> {
// 设置详细属性
});