我正在教授有关新 Java 结构的类(class)。我已经向我的学生介绍了Optional<T>
。想象有一个Point.getQuadrant()
返回 Optional<Quadrant>
(因为有些点根本不在象限内),我们可以将象限添加到 Set<Quadrant>
如果该点位于正 X 象限内,如下所示:
Set<Quadrant> quadrants = ...;
Optional<Point> point = ...;
point
.filter(p -> p.getX() > 0)
.flatMap(Point::getQuadrant)
.ifPresent(quadrants::add);
(这超出了我的想象;如果我犯了错误,请告诉我。)
我的下一步是告诉我的学生,“如果您可以使用函数执行相同的内部过滤和决策,但使用多个对象,那不是很整洁吗?这就是流的用途!”这似乎是完美的延续。我几乎准备好使用流写出相同的表格,但带有点的列表:
Set<Point> points = ...;
Set<Quadrant> quadrants = points.stream()
.filter(p -> p.getX() > 0)
.flatMap(Point::getQuadrant)
.collect(Collectors.toSet());
但是等等!会Stream.flatMap(Point::getQuadrant)
正确地解开Optional<Quadrant>
?看来不是……
我已经读过Using Java 8's Optional with Stream::flatMap ,但我原以为讨论的内容是一些深奥的附带案例,与现实生活无关。但现在我正在实践它,我发现这与我们所做的大多数事情直接相关。
简单地说,如果 Java 现在希望我们使用 Optional<T>
作为新的可选返回习惯用法;如果 Java 现在鼓励我们使用流来处理对象,我们难道不会期望遇到到处都是可选值的映射吗?我们真的必须跳过.filter(Optional::isPresent).map(Optional::get)
系列吗?篮球作为一种解决方法,直到几年后 Java 9 出现?
我希望我只是误解了另一个问题,我只是误解了一些简单的事情,并且有人可以纠正我。 Java 8 肯定没有这么大的盲点,不是吗?
最佳答案
我不知道你的问题的目的是什么。链接问题的答案已经指出,这是 Java 8 的一个缺陷,已在 Java 9 中解决。因此,询问这是否真的是 Java 8 中的缺陷是没有意义的。
除此之外,答案还提到了 .flatMap(o -> o.isPresent()? Stream.of(o.get()): Stream.empty())
用于转换可选,而不是您的 .filter(Optional::isPresent) .map(Optional::get)
。不过,您可以做得更简单:
而不是
.flatMap(Point::getQuadrant)
你可以写
.flatMap(p -> p.getQuadrant().map(Stream::of).orElse(null))
作为 Java 9 的替代方案
.flatMap(p -> p.getQuadrant().stream())
请注意
.map(Point::getQuadrant).flatMap(Optional::stream)
与替代方案相比并没有好多少,除非您对方法引用有非理性的喜爱。
关于java - 可选与 Java Stream 配合不好?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37082972/