每次方法调用后检查对象是否为null

时间:2017-10-31 10:38:12

标签: java java-8

我有这个简单的片段,我希望以更优雅的方式重新设计,可能使用最新的JDK 8功能:

String x = methodCall();
if(x==null) {x=method2();}
if(x==null) {x=method3();}
if(x==null) {x=method4();}

// doing calculation with X

3 个答案:

答案 0 :(得分:9)

您可以使用Streams:

    Optional<String> result= Stream.<Supplier<String>>of(this::method1, this::method2, this::method3)
            .map(Supplier::get)
            .filter(Objects::nonNull)
            .findFirst();
    System.out.println(result.isPresent());

以上代码与此相同(使用Intellij Idea生成)

    Optional<String> result = Optional.empty();
    for (Supplier<String> stringSupplier : Arrays.<Supplier<String>>asList(this::method1, this::method2, this::method3)) {
        String s = stringSupplier.get();
        if (s != null) {
            result = Optional.of(s);
            break;
        }
    }

答案 1 :(得分:4)

这个问题明确提到了Java 8,但也提到了最新的功能&#34;。由于不清楚OP想要的是什么,这个答案是最新的功能。

使用Java 9,您可以使用新的Optional.or方法来简明地实现此逻辑:

import static java.util.Optional.ofNullable;
...
String x = ofNullable(methodCall())
    .or(() -> ofNullable(method2()))
    .or(() -> ofNullable(method3()))
    .or(() -> ofNullable(method4()))
    .orElse(null);

根据您的操作,您可能希望省略.orElse(null)

答案 2 :(得分:2)

你可以通过使用指定的方法摆脱if - 块,但除此之外你不会让它更紧凑。特别是您仍然需要在每种方法后检查null

这是一种方法,如果方法不存在,则使用Optional#ifPresent来应用方法:

public <V> void runIfNotPresent(V value, Runnable method) {
    if (value == null) {
        method.run();
    }
}

以下是使用该方法的代码:

x = methodCall();
runIfNotPresent(x, this::method2);
runIfNotPresent(x, this::method3);
runIfNotPresent(x, this::method4);

// doing calculation with X

请注意,您无法直接使用Optional#isPresentdocumentation),因为其逻辑将被颠倒。但是,这也是一个非常有用的课程,如果您使用 Java 9 ,那么您可能希望使用Optional#ordocumentation),因为其他人已在其答案中显示

或者,您可以编写自己的方法来应用链式方法

public <V> V applyAsLongAsNull(V value, Function<V, V>... methods) {
    // Apply methods
    for (Function<V, V> method : methods) {
        if (value == null) {
            value = method.apply(value);
        } else {
            // Stop as soon as value is not null
            break;
        }
    }

    return value;
}

然后,您可以将methodX转换为接受Function<V, V>值的String并返回可能不同的String值:

public String methodX(String value) {
    // Do something with value
    ...
    // Return value
    return value;
}

最后你会像使用它一样:

String x = methodCall();
x = applyAsLongAsNull(x, this::method2, this::method3, this::method4);

// doing calculation with X