我有这个简单的片段,我希望以更优雅的方式重新设计,可能使用最新的JDK 8功能:
String x = methodCall();
if(x==null) {x=method2();}
if(x==null) {x=method3();}
if(x==null) {x=method4();}
// doing calculation with X
答案 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#isPresent
(documentation),因为其逻辑将被颠倒。但是,这也是一个非常有用的课程,如果您使用 Java 9 ,那么您可能希望使用Optional#or
(documentation),因为其他人已在其答案中显示
或者,您可以编写自己的方法来应用链式方法
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