返回两个选项的总和,如果至少有一个不存在,则返回null

时间:2017-08-02 14:16:35

标签: java java-8 optional

如何使用Java Optional API以更优雅的方式重写以下代码:

first == null || second == null ? null : first + second;

如果两个变量中的任何一个变为null或其他变量在其他地方,则代码应返回null

4 个答案:

答案 0 :(得分:9)

我可以理解,也许你开始学习如何操作Optional。这个怎么样?

String result = 
    Optional.ofNullable(first)
            // v--- the trick is use the `flatMap` here.
            .flatMap(left -> Optional.ofNullable(second).map(right-> left + right))
            .orElse(null);

答案 1 :(得分:4)

如果你正在接受空值并返回空值,那么使用Optional并不是非常有用。您可以将代码包装在Optional中,但它看起来就像普通的空检查代码,并且有一些额外的垃圾。仅使用Optional来检查空值仍然只是检查空值。如果您将整个方法重写为完全Optional,则会得到如下内容:

public Optional<Integer> add(Optional<Integer> first, Optional<Integer> second)
{
    return first.flatMap(left -> second.map(right -> left + right))
}

请注意,通过充分利用Optional接口,您不再需要担心null的特殊处理。此外,如果有人调用您的方法,则返回类型更加具体地说明在null / empty输入上发生的事情。

如果输入超出您的控制范围,正如您在评论中指出的那样,您可以使用Optional将其打包在Optional.ofNullable中,然后继续。如果你的输入和输出返回类型都是固定的,那么就像Optional一样好,你就没有好用它。

答案 2 :(得分:3)

如果我们坚持你的要求:

  

如果两个变量中的任何一个为null或其总和在其他位置,则代码应返回null。

然后你根本不应该使用Optional。它只会降低您的代码的可读性,并且难以维护。

Optional的真正力量并不在于它的优雅,以避免无效检查(也不具备链式方法的诱惑潜力),而是表现为封装任何一种礼物的表现力或者缺席价值。使用它的最佳方式是作为方法的返回值。

在您的示例中,正如您所说,如果任一操作数为null,该方法应返回null,则您不会利用Optional的潜力。另一方面,如果您有一个返回Optional的方法(空或带总和),您将按预期使用它:

public Optional<Integer> firstPlusSecond() {
    Optional<Integer> a = Optional.ofNullable(first);
    Optional<Integer> b = Optional.ofNullable(second);

    if (!a.isPresent() || !b.isPresent()) {
        return Optional.empty();
    }

    return Optional.of(a.get() + b.get());
}

这实际上清楚地表达了您的意图,即返回的Optional为空(如果一个操作数为null)或保留first + second的结果。

如果firstsecond都有可选的getter ,那就更好了:

public Optional<Integer> first() {
    return Optional.ofNullable(first);
}

public Optional<Integer> second() {
    return Optional.ofNullable(second);
}

这样,上面的firstPlusSecond()方法现在转为:

public Optional<Integer> firstPlusSecond() {
    Optional<Integer> a = first();
    Optional<Integer> b = second();

    if (!a.isPresent() || !b.isPresent()) {
        return Optional.empty();
    }

    return Optional.of(a.get() + b.get());
}

其中,IMO,是更好的代码。

甚至更好,正如@ holi-java在评论中所建议的那样:

public Optional<Integer> firstPlusSecond() {
    Optional<Integer> a = first();
    Optional<Integer> b = second();

    return a.isPresent() && b.isPresent() ? 
            Optional.of(a.get() + b.get()) : 
            Optional.empty();
}

或者,正如@ holi-java建议的那样,如果您不想为firstsecond创建可选的getter,但仍希望返回Optional ,你可以这样做:

public Optional<Integer> firstPlusSecond() {
    return first != null && second != null ? 
            Optional.of(first + second) : 
            Optional.empty();
}

答案 3 :(得分:1)

这是我使用java流的解决方案

private Integer sum(Integer ...additions) {
  return Arrays.stream(additions).filter(Objects::nonNull).reduce(0, Integer::sum);
}