Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/377.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 多个可选实例的逻辑或逻辑?_Java_Java Stream_Optional - Fatal编程技术网

Java 多个可选实例的逻辑或逻辑?

Java 多个可选实例的逻辑或逻辑?,java,java-stream,optional,Java,Java Stream,Optional,是否有一种更优雅的方式来使用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()) {

是否有一种更优雅的方式来使用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);
  }
}
这就是我目前所得到的,但我们能做得更好吗

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()
    {
    }
}
公共类选项
{
/**
*@param选项返回的值的类型
*@param suppliers返回供应商的一个或多个供应商
*@返回第一个可选的{@link Optional#isPresent()isPresent()}
*/
公共静态或可选(供应商…供应商)
{
对于(供应商:供应商)
{
可选候选者=supplier.get();
if(candidate.isPresent())
返回候选人;
}
返回可选的.empty();
}
/**
*防止施工。
*/
私人期权()
{
}
}

可选的
有一个
orElse
方法;如果调用此函数,它将返回
可选
中的值(如果该值不为空),或者返回传递给
的值(如果该值为空)

因此,您可以使用嵌套的
orElse
调用,如下所示:

Float output = input.map(function1).map(function2)
    .orElse(input.map(function3).map(function4)
        .orElse(input.map(function5).map(function6)
            .orElse(0.0f)));
请注意,在这种情况下,最终结果不是
可选
,而是
浮点
。如果您不希望在没有任何映射返回值时使用默认返回值,例如
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"))));

在这种情况下,我不太喜欢
供应商
方案,可能更喜欢这种方法:

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();
}
publicstaticvoidmain(字符串[]args){
浮动x=1.0f;
最终可选输入=可选的(x);
可选输出=firstPresent(输入,(a)->a.map(函数1).map(函数2),
(a) ->a.map(功能3).map(功能4),
(a) ->a.map(函数5).map(函数6));
}
@安全变量
公共静态可选firstPresent(可选输入、函数…函数){
for(函数:函数){
最终可选输出=函数。应用(输入);
if(output.isPresent()){
返回输出;
}
}
返回可选的.empty();
}

通过Java8谓词(Yosi Lev)实现“多条件”逻辑AND的方法:

publicstaticvoidmain(字符串[]args){
Optional stringOptional=Optional.of(“这是一个字符串”);
谓词isNotNull=s->s!=null;
谓词isSizeGT0=s->s.length()>0;
谓词isSizeGT20=s->s.length()>20;
//使用所有需要批准的谓词调用isOk():
System.out.println(isOk(stringOptional,isNotNull,isSizeGT0,isSizeGT20));
}//main()
@安全变量
私有静态布尔isOk(可选inp、谓词…谓词){
//对输入强制执行所有谓词。。
布尔b=Arrays.stream(谓词).allMatch(pr->pr.test(inp.get());
返回b;
}

未对此进行测试。Java8Lambdas使用数组流。这将评估所有供应商,这不是我想要的。我希望返回以按顺序评估供应商,并在其中一个供应商返回非空值时立即停止。
Arrays.stream(suppliers).map(Supplier::get).filter(可选::isPresent).findFirst().orElse(可选::empty)
这不会导致总是对函数3到函数6进行求值吗?@您可以使用构造函数传递lambda,以避免急于求值。这对我不起作用,因为它返回
t
而不是
可选的
。我有3种方法来查找值,但这3种方法都可能返回空值。我会将您的
函数重命名为
firstOf
,然后使用它。在我看来,这是一个很好的解决方案。在我的例子中,
供应商
从外部代码块捕获
输入
,但是是的,这更明确。@Gili这样,您也可以更容易地重用lambdas/函数。供应商需要为每个输入构建。我并不真正重用lambda/函数,但这是一个很好的观点。谁知道我将来可能需要什么。。。
Float output = input.map(function1).map(function2)
    .orElse(input.map(function3).map(function4)
        .orElse(input.map(function5).map(function6)
            .orElseThrow(() -> new IllegalStateException("No result"))));
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();
}
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; 
}