由于您需要压平流数据,即翻转类型的每个元素
OffenceEntity
分成一组元件,
mapToInt()
不是正确的操作。为此,您可以使用
flatMap()
(或它的味道
flatMapToInt()
).
区分两种操作
map()
和
flatMap()
,记住一个简单的原则:
-
当你需要的时候
一对一
转型
使用
地图
或者是味道
-
对于
一对多
转型
-
flatMap()
或者是味道。
由于Java 16,我们还可以利用
mapMulty()
以使流中的数据变平。但它是一种特殊用途的工具,而不是一种常见的选择。除了平坦化之外,此操作还允许过滤掉流元素,因此与
flatMap()
它将一个元素变成
1+
(
一个或多个
)元素,
mapMulty()
生产
0+
(
零或更多
)元素。
flatMap()
flatMap()
期望函数作为参数,该函数接受元素并生成流(
这也是
map
和
flatMap
).
流数据扁平化后,我们需要进行过滤
OffenceDetailsEntity
具有合适日期和摘录的对象
penaltyPoints
。可以使用
filter()
+
mapToInt()
.
public int countPenaltyPointsTest(Set<OffenceEntity> offences, LocalDate date) {
return offences.stream() // Stream<OffenceEntity>
.flatMap(offence -> offence.getDetails().stream()) // Stream<OffenceDetailsEntity>
.filter(ode -> date.isAfter(ode.getStartDate()) // Stream<OffenceDetailsEntity>
&& date.isBefore(ode.getEndDate()))
.mapToInt(OffenceDetailsEntity::getPenaltyPoints) // IntStream
.sum();
}
mapMulty()
此操作允许结合命令式编程功能(
即循环和条件语句
)进入流管道。
如前所述,这是一个
专用工具
有很多特殊之处,应该用心去运用。
这是引用的
API Note
规定何时使用
mapMulty()
:
此方法优于
flatMap
在以下情况下:
-
将每个流元素替换为
小的
(
可能为零
)元素的数量。使用此方法可以避免创建
一个新的
Stream
根据需要,用于每组结果元素的实例
通过
flatMap
.
-
当它是
更易于使用
一
命令式方法
用于生成结果元素,而不是以
流动
.
例如,
mapMulty()
能够替代组合
flatMap()
+
滤器
,或多个
flatMap()
操作。
它需要类型为的参数
BiConsumer
,即消费者,反过来
两个论点
:
流元素
和一个
消费者
结果类型的。提供给消费者的每个值都将成为一个新的流元素,取代初始元素。
以下是如何使用实现此方法
mapMultyToInt()
:
public int countPenaltyPointsTest(Set<OffenceEntity> offences, LocalDate date) {
return offences.stream()
.mapMultiToInt((offence, consumer) ->
offence.getDetails().forEach(ode -> {
if (date.isAfter(ode.getStartDate()) && date.isBefore(ode.getEndDate()))
consumer.accept(ode.getPenaltyPoints());
}))
.sum();
}
有关如何使用的更多示例和信息
mapMulty()
,看看
this question
.