flatMap后是否可以引用原始对象?
例如:
.flatMap(passenger-> passenger.getAncillaries().stream())
.forEach(ancillary -> {
[Can here reference passenger?]
foo(passenger, ancillary); ?????
}
谢谢。
问候。
在 Java 17 中,您可以使用
record
来做到这一点(旧版本中的类也可以):
record PassengerAndAncillary(Passenger passenger, Ancillary ancillary) {}
//
passengers.flatMap(passenger-> passenger.getAncillaries()
.stream()
.map(ancillary -> new PassengerAndAncillary(passenger, ancillary) )
.forEach(pa -> {
foo(pa.passenger(), pa.ancillary());
});
然后更好:让 foo 接受 PassengerAndAncillary,你就完成了:
.forEach(this::foo)
如果不想自己上课,也可以用:
然而,在这种情况下,如果您不使用
Stream
,最好不要使用Stream
:
passengers.forEach(passenger -> {
passenger.getAncillaries().forEach(ancillary -> {
foo(passenger, ancillary);
});
});
-- 编辑(评论):
我会说之前/之后的过滤归结为性能问题:
forEach
的循环会更好,因为你根本没有使用 Stream
.flatMap
之前进行:生成的流将更短,从而减少对 flatMap
函数的调用(以及更少的 record PassengerAndAncillary
)。forEach
之前执行PassengerAndAncillary
。在代码行中:
.flatMap(passenger-> passenger.getAncillaries().stream())
// Only Ancillaries type objects exist in the stream
所以你不能写这样的代码:
.forEach(ancillary -> {
passenger.getName();// can not access to the passenger object
}
正确答案:
.flatMap(passenger-> passenger.getAncillaries().stream())
.forEach(item -> {
item.getXXX();//item references 【passenger.getAncillaries()】
}
使用
flatMap
的另一个替代方法是将 mapMulti(Java 16) 与 Map.entry 结合使用
mapMulti
,它获取流对象和消费者。请注意,mapMulti 是类型见证的,以反映放置在流上的新类型。在这种情况下Map.Entry
Map.Entry
中打包。 Consumer.accept
将其放在流中以进行后续处理。passengers.stream()
.filter(passenger -> passenger.isSomething)
.<Map.Entry<Passenger, Ancillary>>mapMulti((passenger, consumer) -> {
for (Ancillary ancillary : passenger.getAncillaries) {
consumer.accept(
Map.entry(passenger, ancillary));
}
})
.forEach(e -> foo(e.getKey(), e.getValue()));