【问题标题】:Rewrite if-statement using Optional map and filter使用可选映射和过滤器重写 if 语句
【发布时间】:2018-10-31 08:41:17
【问题描述】:

我有一个接受 Optional<LocalDateTime> 的谓词,我想检查它是否存在并且 LocalDateTime 在当前日期之前。

我可以使用如下所示的 if 语句来编写它:

@Override
public boolean test(Optional<ResetPassword> resetPassword) {
    if (resetPassword.isPresent()) {
        if (!resetPassword.get().getValidUntil().isBefore(LocalDateTime.now())) {
            throw new CustomException("Incorrect date");
        }
        return true;
    }
    return false;
}

如何使用Optional.mapOptional.filter 函数重写它?

【问题讨论】:

  • @KarelG Optional 也有 mapfilter 方法。
  • 你不应该使用Optional 作为任何东西的参数。它只能用作返回类型。
  • @marstran “你永远不应该使用 Optional 作为任何东西的参数。” 作为一个不合格的断言声明,这是完全错误的。这是风格问题。将 optional 作为参数类型可以让读者清楚地知道该参数可能为 null,这使得代码更易于使用。
  • @LiolikasBolikas:mapfilter 似乎没有解决问题的好方法。我认为您的解决方案尽可能好。我认为这很难的原因是,你想要的结果组合不能很好地转化为Optional 的逻辑。在您的情况下,您想使用booleanResetPassword 和异常,这并不适合模型。我认为...
  • 我也反对使用Optional 作为方法参数。但是,如果打算将其用作Predicate,则可能需要在这种情况下使用它。这将让您获取Optional&lt;ResetPassword&gt; 流并使用此谓词过滤它们。虽然从语义上讲,这种特殊情况似乎有点奇怪,但可能还有其他有用的情况。更令人担忧的是,此方法在某些情况下会引发异常,这使得它完全不适合大多数用作 Predicate 的用途。

标签: java validation lambda optional predicate


【解决方案1】:

你不应该使用Optional 作为任何东西的参数。相反,您应该让您的函数采用ResetPassword,并且仅当Optional 的值存在时才调用它。 像这样:

public void test(ResetPassword resetPassword) {
    if (!resetPassword.getValidUntil().isBefore(LocalDateTime.now())) {
        throw new CustomException("Incorrect date");
    }
}

然后这样称呼它:

resetPasswordOptional
    .ifPresent(rp -> test(rp));

【讨论】:

  • “你不应该使用 Optional 作为任何东西的参数。” 作为一个不合格的断言声明,这是完全错误的。这是风格问题。将可选作为参数类型让读者清楚地知道它可能为空。
  • @Lii 这当然不是一个无条件的陈述。这是一个源自布赖恩·戈茨本人的声明。见stackoverflow.com/a/26328555/4137489
【解决方案2】:

希望这个对你有帮助,另外,注意你抛出的异常,如果是RuntimeException你的应用会在错误情况下崩溃。

 public boolean test(Optional<ResetPassword> resetPassword) {
        return resetPassword.isPresent() && resetPassword
                .map(ResetPassword::getValidUntil)
                .filter(localDateTime -> localDateTime.isBefore(LocalDateTime.now()))
                .orElseThrow(() -> new CustomException("Incorrect date")) != null;
    }

【讨论】:

  • 应该可以!我认为海报已经拥有的内容更清晰,但这更短,至少它使用了mapfilter! (如果这是你的目标……)
猜你喜欢
  • 2017-08-23
  • 2012-02-25
  • 1970-01-01
  • 2016-01-02
  • 1970-01-01
  • 1970-01-01
  • 2015-05-28
  • 1970-01-01
  • 2019-02-17
相关资源
最近更新 更多