我有一个字符串和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仅用于记录的遗留部分。希望这澄清了我对这种方法的意图。
答案 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));