【问题标题】:Optional doesn't play well with Java Stream?Optional 不能与 Java Stream 配合使用?
【发布时间】:2016-05-06 23:52:12
【问题描述】:

我正在教授有关新 Java 结构的课程。我已经向我的学生介绍了Optional<T>。假设有一个Point.getQuadrant() 返回一个Optional<Quadrant>(因为有些点根本不在象限中),如果该点位于正X象限,我们可以将象限添加到Set<Quadrant>,如下所示:

Set<Quadrant> quadrants = ...;
Optional<Point> point = ...;
point
    .filter(p -> p.getX() > 0)
    .flatMap(Point::getQuadrant)
    .ifPresent(quadrants::add);

(这不是我的想法;如果我犯了错误,请告诉我。)

我的下一步是告诉我的学生,“如果您可以使用函数执行相同的内部过滤和决策,但使用多个对象,那不是很好吗?这就是流的用途!”这似乎是完美的转场。我几乎准备好使用流写出相同的表格,但带有 list 点:

Set<Point> points = ...;
Set<Quadrant> quadrants = points.stream()
    .filter(p -> p.getX() > 0)
    .flatMap(Point::getQuadrant)
    .collect(Collectors.toSet());

但是等等! Stream.flatMap(Point::getQuadrant) 会正确解开 Optional&lt;Quadrant&gt; 吗?好像没有……

我已经阅读了 Using Java 8's Optional with Stream::flatMap ,但我认为讨论的内容是一些与现实生活无关的深奥的侧面案例。但现在我正在发挥作用,我发现这与我们所做的大多数事情都直接相关。

简单地说,如果 Java 现在希望我们使用 Optional&lt;T&gt; 作为新的可选返回习语;如果 Java 现在鼓励我们使用流来处理我们的对象,难道我们不希望到处都遇到到可选值的映射吗?我们真的必须跳过一系列.filter(Optional::isPresent).map(Optional::get) 箍作为一种解决方法,直到Java 9 几年后出现?

我希望我只是误解了另一个问题,我只是误解了一些简单的事情,有人可以让我直截了当。 Java 8 肯定没有这么大的盲点,不是吗?

【问题讨论】:

  • 为什么是flatMap?另外,如果它打算返回Optional&lt;Quadrant&gt;,你怎么会收集到Set&lt;Quadrant&gt;?你的意思是只收集那些存在的吗?
  • 是的,我只想收集存在的象限。
  • 然后mapPoint 转换为Optional&lt;Quadrant&gt;,然后使用Optional#isPresent 过滤,然后将map 使用getcollect 返回到您的Set&lt;Quadrant&gt;
  • 我现在意识到你已经知道了。
  • 是的,好主意@zapl。我想知道为什么没有Streamable&lt;T&gt; 接口?看起来很明显。

标签: java java-stream optional


【解决方案1】:

我不确定你的问题是针对哪里的。链接问题的答案已经表明,这 Java 8 的一个缺陷,在 Java 9 中得到了解决。因此,问这是否真的是 Java 8 中的一个缺陷是没有意义的。

除此之外,答案还提到.flatMap(o -&gt; 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)

与替代方案相比并没有那么好,除非您对方法引用有非理性的亲和力。

【讨论】:

    猜你喜欢
    • 2014-05-08
    • 2022-07-07
    • 1970-01-01
    • 1970-01-01
    • 2011-09-19
    • 1970-01-01
    • 2019-06-11
    • 1970-01-01
    • 2021-06-16
    相关资源
    最近更新 更多