Java8可选fire一个方法,如果为null,另一个if not not null Best Approach

时间:2016-01-13 04:25:30

标签: java lambda java-8 optional

我有一个字符串和B字符串,app如果不是null则更喜欢A,并调用转换方法changeA()。但是,如果A为null,则它将使用B并调用方法changeB()。两种转换方法都返回相同的对象类型Result。但有一点需要注意的是str B也可能为null,如果那种情况返回null。

如何使用JDK中的optional和lambda表达式来处理此问题。

我有以下代码库:

changeA(){
..
}

changeB(){
..
}

aMethod(){
    Optional<String> optA=Optional.ofNullable(a);
    Result result = optA.map( aStr -> this.changeA( aStr ) ).orElse( this.changeB( bStr ) );
}

这看起来有点奇怪,因为orElse方法使用的变量不在lambda的范围内。我可以知道最好的方法吗?

也许我应该说明为什么我选择了Optional。我希望我的团队的开发人员明白,即使字符串A是首选,它也可能是null,必须处理,因为代码的一部分是敏感的。字符串B仅用于记录的遗留部分。希望这澄清了我对这种方法的意图。

2 个答案:

答案 0 :(得分:6)

仅在必要时调用changeB,您可以使用以下构造:

result = Optional.ofNullable(aStr).map(this::changeA).orElseGet(
          () -> Optional.ofNullable(bStr).map(this::changeB).orElse(null));

请注意,您可以在没有选项的情况下执行此操作:

result = aStr != null ? changeA(aStr) :
         bStr != null ? changeB(bStr) :
         null;

这要短得多,并生成更清晰的字节码。

另一种功能方式是使用供应商流:

Supplier<Result> aSupplier = () -> aStr == null ? null : changeA(aStr);
Supplier<Result> bSupplier = () -> bStr == null ? null : changeB(bStr);

result = Stream.of(aSupplier, bSupplier).map(Supplier::get)
               .filter(Objects::nonNull).findFirst().orElse(null);

此方法可扩展:您可以向流中添加更多供应商。如果您不喜欢三元运营商,则可以将aStr == null ? null : changeA(aStr)替换为Optional.ofNullable(aStr).map(this::changeA).orElse(null)

答案 1 :(得分:2)

您可以使用以下内容:

Optional<String> optA = Optional.ofNullable(aStr).map(this::changeA);
Optional<String> optB = Optional.ofNullable(bStr).map(this::changeB);
result = optA.orElse(optB.orElse(null));