使用Java核心API表示以下算法是否有更优雅的方法?
Optional<Float> input = Optional.of(A);
Optional<Float> output = input.map(function1).map(function2);
if (!output.isPresent())
{
output = input.map(function1).map(function2);
if (!output.isPresent())
{
output = input.map(function3).map(function4);
if (!output.isPresent())
output = input.map(function5).map(function6);
}
}
也就是说,不是嵌套isPresent()
的多个调用,而是要调用map()
之类的方法,但只有在没有值的情况下才会调用它。
在一个理想的世界里,我想调用以下内容:
Optional<Float> output = input.or(input.map(function1).map(function2), input.map(function2).map(function3), input.map(function4).map(function5));
这是我迄今为止所做的,但我们可以做得更好吗?
public class Optionals
{
/**
* @param <T> the type of value returned by the Optionals
* @param suppliers one or more suppliers that return a supplier
* @return the first Optional that {@link Optional#isPresent() isPresent()}
*/
public static <T> Optional<T> or(Supplier<Optional<T>>... suppliers)
{
for (Supplier<Optional<T>> supplier: suppliers)
{
Optional<T> candidate = supplier.get();
if (candidate.isPresent())
return candidate;
}
return Optional.empty();
}
/**
* Prevent construction.
*/
private Optionals()
{
}
}
答案 0 :(得分:2)
Optional
有一个orElse
方法;如果你调用它,它将返回Optional
中的值(如果它不为空),或者传递给orElse
的值(如果它为空)。
所以你可以使用嵌套的orElse
调用,如下所示:
Float output = input.map(function1).map(function2)
.orElse(input.map(function3).map(function4)
.orElse(input.map(function5).map(function6)
.orElse(0.0f)));
请注意,最终结果不是Optional<Float>
而是Float
。如果您没有想要一个默认返回值,例如0.0f
,当没有映射返回值时,您可以例如让它抛出异常:
Float output = input.map(function1).map(function2)
.orElse(input.map(function3).map(function4)
.orElse(input.map(function5).map(function6)
.orElseThrow(() -> new IllegalStateException("No result"))));
答案 1 :(得分:1)
return Arrays.stream(suppliers).filter(supplier -> supplier.get().isPresent()).toArray();
答案 2 :(得分:0)
在这种情况下,我不喜欢Supplier
计划,可能更喜欢这种方法:
public static void main(String[] args) {
Float x = 1.0f;
final Optional<Float> input = Optional.of(x);
Optional<Float> output = firstPresent(input, (a) -> a.map(FUNCTION1).map(FUNCTION2),
(a) -> a.map(FUNCTION3).map(FUNCTION4),
(a) -> a.map(FUNCTION5).map(FUNCTION6));
}
@SafeVarargs
public static <I,O> Optional<O> firstPresent(Optional<I> input, Function<Optional<I>, Optional<O>>... functions) {
for (Function<Optional<I>, Optional<O>> function : functions) {
final Optional<O> output = function.apply(input);
if(output.isPresent()) {
return output;
}
}
return Optional.empty();
}
答案 3 :(得分:0)
通过Java8谓词实现'多条件'逻辑AND的方法(作者Yosi Lev):
public static void main(String[] args) {
Optional<String> stringOptional = Optional.of( "this is a string" );
Predicate<String> isNotNull = s-> s != null;
Predicate<String> isSizeGT0 = s-> s.length() > 0 ;
Predicate<String> isSizeGT20 = s-> s.length() > 20 ;
// calling isOk() with all required Predicates to be approved:
System.out.println(isOk(stringOptional, isNotNull, isSizeGT0, isSizeGT20));
}//main()
@SafeVarargs
private static <I> boolean isOk(Optional<I> inp, Predicate<I>... predicates){
// Enforce all predicates on input..
boolean b = Arrays.stream( predicates ).allMatch( pr->pr.test( inp.get()));
return b;
}