gpt4 book ai didi

java - 根据两个 Optionals 的值调用不同的方法

转载 作者:搜寻专家 更新时间:2023-10-30 21:47:21 25 4
gpt4 key购买 nike

在使用 Java 8 Optionals 时,我经常遇到以下情况。我有两个 Optional 对象,然后我想根据这些 Optional 的值 (ifPresent) 调用不同的方法。

这是一个例子:

void example(Optional<String> o1, Optional<String> o2) throws Exception {
if (o1.isPresent() && o2.isPresent()) {
handler1(o1.get(), o2.get());
} else if (o1.isPresent()) {
handler2(o1.get());
} else if (o2.isPresent()) {
handler3(o2.get());
} else {
throw new Exception();
}
}

但是,这个 if-else 语句链似乎不是使用 Optional 的正确方法(毕竟,添加它们是为了避免在代码中的任何地方编写这些 if-else 检查)。

使用 Optional 对象的正确方法是什么?

最佳答案

你说你经常使用这样的结构,所以我建议引入一个Helper class:

final class BiOptionalHelper<F, S> {
private final Optional<F> first;
private final Optional<S> second;

public BiOptionalHelper(Optional<F> first, Optional<S> second){
this.first = first;
this.second = second;
}

public BiOptionalHelper<F, S> ifFirstPresent(Consumer<? super F> ifPresent){
if (!second.isPresent()) {
first.ifPresent(ifPresent);
}
return this;
}

public BiOptionalHelper<F, S> ifSecondPresent(Consumer<? super S> ifPresent){
if (!first.isPresent()) {
second.ifPresent(ifPresent);
}
return this;
}

public BiOptionalHelper<F, S> ifBothPresent(BiConsumer<? super F, ? super S> ifPresent){
if(first.isPresent() && second.isPresent()){
ifPresent.accept(first.get(), second.get());
}
return this;
}

public <T extends Throwable> void orElseThrow(Supplier<? extends T> exProvider) throws T{
if(!first.isPresent() && !second.isPresent()){
throw exProvider.get();
}
}
}

然后可以这样使用:

new BiOptionalHelper<>(o1, o2)
.ifBothPresent(this::handler1)
.ifFirstPresent(this::handler2)
.ifSecondPresent(this::handler3)
.orElseThrow(Exception::new);

不过,这只是将您的问题转移到了一个单独的中。

注意:以上代码可能被重构为完全不使用OptionalisPresent() 检查。只需将 null 用于 firstsecond 并将 isPresent() 替换为 null -检查。

因为在字段中存储 Optional 或首先接受它们作为参数通常是一个糟糕的设计。正如 JB Nizet 已经在对该问题的评论中指出的那样。


另一种将逻辑转移到通用辅助方法中的方法:

public static <F, S, T extends Throwable> void handle(Optional<F> first, Optional<S> second, 
BiConsumer<F, S> bothPresent, Consumer<F> firstPresent,
Consumer<S> secondPresent, Supplier<T> provider) throws T{
if(first.isPresent() && second.isPresent()){
bothPresent.accept(first.get(), second.get());
} else if(first.isPresent()){
firstPresent.accept(first.get());
} else if(second.isPresent()){
secondPresent.accept(second.get());
} else{
throw provider.get();
}
}

然后可以这样调用:

handle(o1, o2, this::handler1, this::handler2, this::handler3, Exception::new);

但说实话还是有点乱。

关于java - 根据两个 Optionals 的值调用不同的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51847513/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com