是否可以直接将对象扩展为流?
我目前的做法是:
private BigDecimal getNodeScore(Optional<Node> node) {
return node.map(Node::getBranches)
.orElseGet(Collections::emptySet)
.stream()
.filter(Branch::isValid)
.flatMap(Branch::getLeafs)
.map(Leaf::getScore)
.reduce(BigDecimal::ZERO, BigDecimal::add);
}
它工作得很好(是的,我知道它现在很丑陋)但是只是讨厌使用orElseGet和steam从Optional转换为Stream所以我想知道是否有任何方法可以将Optional扩展为Stream ?
我需要的是:
private BigDecimal getNodeScore(Optional<Node> node) {
return node.mapToStream(Node::getBranches) // <-- Want something similar
.filter(Branch::isValid)
.flatMap(Branch::getLeafs)
.map(Leaf::getScore)
.reduce(BigDecimal::ZERO, BigDecimal::add);
}
我知道我总是可以创建一个辅助函数并用第一个调用来包装:
optionalToStream(node.map(Node::getBranches))
但仍然想知道是否有更优雅的方式。
答案 0 :(得分:2)
您始终可以使用Optional
将Stream
转换为由{0}组成的optional.map(Stream::of).orElseGet(Stream::empty)
。如果流的项目可以提供Stream
,您实际上想要处理,您可以使用flatMap
将流的项目替换为评估的结果流,或者如果{{1空的。
E.g。
Optional
或
Optional<Node> optional=Optional.empty();
optional.map(Stream::of).orElseGet(Stream::empty)
.map(Node::getBranches).flatMap(Collection::stream)
// follow-up operations
但在这种特殊情况下你也可以把它融合成一个操作
optional.map(Stream::of).orElse(Stream.empty())
.flatMap(node -> node.getBranches().stream())
// follow-up operations
(但我认为在优化之前了解一般模式是值得的...)
答案 1 :(得分:1)
它运作得很好(是的,我知道它现在很丑陋)但是只是讨厌使用orElseGet和steam从Optional转换为Stream
说实话,我认为你的做法并不丑陋。您仍然可以使用isPresent()
来测试可选项是否包含值。
private BigDecimal getNodeScore(Optional<Node> node) {
return node.isPresent() ? node.get()
.getBranch()
.stream()
.filter(Branch::isValid)
.flatMap(Branch::getLeafs)
.map(Leaf::getScore)
.reduce(BigDecimal.ZERO, BigDecimal::add) : BigDecimal.ZERO;
}
如果您认为情况更糟,另一种解决方法是在Node类中提供一个直接返回Stream<Branch>
的方法。
private BigDecimal getNodeScore(Optional<Node> node) {
return node.map(Node::getBranchesStream)
.orElseGet(Stream::empty)
.filter(Branch::isValid)
.flatMap(Branch::getLeafs)
.map(Leaf::getScore)
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
是否可以直接将对象扩展为流?
是的,Stream.of
用于此目的,但由于getBranch
返回Set
,因此您不需要它,因此您只需要调用stream()
它来得到结果流。