【问题标题】:Can Java Optional be used for flow control?Java Optional 可以用于流量控制吗?
【发布时间】:2017-04-23 15:30:14
【问题描述】:

我找不到使用 Java 的 Optional 执行以下操作的方法:

if (SOME_OBJECT != null) {
  doSomething(SOME_OBJECT);
} else {
  doSomethingElse();
}

使用Optional 并不是指用Optional.ofNullable(SOME_OBJECT).isPresent() 替换SOME_OBJECT == null,这比简单地检查是否为空要长得多。

我的期望是这样的:

Optional.ofNullable(SOME_OBJECT)
  .ifPresent(this::doSomething)
  .orElse(this::doSomethingElse);

我找不到像我刚刚写的那样的 API。它存在吗?如果是这样,它是什么?如果不是,为什么不呢? :)

第二段代码看起来像一个反模式:(为什么?也许 Java 的架构师故意阻止了这种语法......

【问题讨论】:

  • 令人惊讶的是ifPresent 没有返回Optional,而且似乎没有ifAbsent
  • 我认为第二段代码可能是反模式,因为它进行了三个方法调用,并且似乎还进行了更多检查(ifPresentorElse 必须重新检查结果来自ofNullable。它似乎至少和 if-then 一样复杂,而且难以维护。所有缺点(即使很小),没有优点。
  • @markspace:我倾向于对Optional 整体有这种感觉。 :-) 但是我没有在愤怒中使用它(我已经好几年没有做过任何严肃的 Java 了),所以我认为这是反动和无知的...... :-)
  • @T.J.Crowder 我认为Optional 是作为流实现的一部分引入的。它在流的底层使用以防止NullPointerExceptions。从这个角度来看,我认为这是有道理的——作为一个更大的内聚框架的一部分。随机使用Optional 可能不会对其设计或实现产生凝聚力的影响,您需要一些充分的理由来使用这些类型的对象。
  • 如果您已经有一个包含 null 的变量,请保留您的 if 并感到高兴。对于单个条件,将其包装到 Optional 中没有任何好处。

标签: java java-8 optional nullable


【解决方案1】:

正如 BdoubleB97 (Bdubzz) 所说,Java 9 将实现 Optional#ifPresentOrElse,它将采用 Consumer<T>,如果存在 Optional<T>,则将应用该 Runnable,如果 Optional<T> 将执行 Runnable是空的。

您可以立即更新到 Java 9 Early Access 版本,也可以使用以下内容自行构建该方法:

public <T> void ifPresentOrElse(Optional<T> optional, Consumer<? super T> action, Runnable emptyAction) {
    if (optional.isPresent()) {
        action.accept(optional.get());
    } else {
        emptyAction.run();
    }
}

【讨论】:

    【解决方案2】:

    正如Blog Article 中提到的,Optionals 将在 Java 9 中获得一个新方法:void ifPresentOrElse(Consumer&lt;? super T&gt; action, Runnable emptyAction)。因此,对于 Java 8,您目前还没有类似的东西。

    【讨论】:

    【解决方案3】:

    如前所述,Java 8 没有一个结构可以完全按照您的意愿行事。

    我知道,它很丑陋,比简单的 if/then/else 可读性差得多,但你可以这样做:

    Optional.ofNullable(someObject)
            .map(obj -> {
                System.out.println("present");
                return obj;
              })
            .orElseGet(() -> {
                System.out.println("not present");
                return null;
              });
    

    唯一的副作用是你总是返回一些东西。
    或者另一方面,您可以干净利落地处理 isPresent() 的案例。

    Optional.ofNullable(someObject).ifPresent(obj -> {
      System.out.println("present");
    });
    

    【讨论】:

    • 虽然可能,但我想不出这是一个好主意的情况。它比if-else 复杂得多,并且未使用的返回值进一步混淆了意图。 (除了滥用map()orElseGet()的副作用)。
    • 对...我只是想了解我们是否只能使用 Java 8 来避免这个限制。但结果有点太丑了:)
    猜你喜欢
    • 2012-12-27
    • 1970-01-01
    • 1970-01-01
    • 2018-07-19
    • 1970-01-01
    • 1970-01-01
    • 2017-05-14
    • 1970-01-01
    • 2011-07-10
    相关资源
    最近更新 更多