从 Java 基础到掌握 — 第 6 集
使用 Lambda、Stream 和Optional 创建数据流
该博客上撰写的文章是出于教学目的而创建的。 另外,文章中的信息可能不正确,请谨慎。
在集合中选择、转换和组合满足条件的值的代码经常出现。 Lambda 和 Stream 表达了数据经过操作流的阶段。
拉姆达
Predicate<Monster> isAlive = monster -> monster.getHealth() > 0;
Function<Monster, String> getName = Monster::getName;
Lambda 允许将操作作为值传递。 当以相同的函数形式使用现有方法时,方法引用是简洁的。
流管道
List<String> targetNames = monsters.stream()
.filter(Monster::isAlive)
.sorted(Comparator.comparingInt(Monster::getHealth))
.limit(3)
.map(Monster::getName)
.toList();
流程是将活着的怪物按照体力强弱排序,得到三个名字。 中间操作通常在调用最终操作时执行。
一旦流被消耗,同一个流就不能再次使用。 您必须重复查询原始集合或将结果存储为列表。
Optional
Optional<Item> item = repository.find(10);
String name = item
.map(Item::getName)
.orElse("Unknown");
可选向返回类型指示该值可能存在也可能不存在。 如果直接调用get(),不会再次丢失任何处理,因此请使用orElse、map、ifPresent等操作。
可选通常用于表示没有返回值,而不是对所有字段和参数使用它。
性能和可读性
流并不总是比循环快,并且可能会导致操作对象和结果列表较小。 最好从易于阅读的流程开始,然后仅将在实际测量中导致问题的重复路径更改为简单的循环。
lambda 和流的目的不是使代码尽可能短。 目标是使数据处理步骤(例如过滤、转换和排序)可读且无副作用。