【问题标题】:Java streams, cannot convert from Optional<BooleanExpression> to BooleanJava 流,无法从 Optional<BooleanExpression> 转换为 Boolean
【发布时间】:2021-06-05 23:03:17
【问题描述】:

所以我的情况是我有一个布尔评估器。本质上,它们都是自定义类型BooleanExpression。每个值都有一个方法.evaluate(context),它接受变量映射context,并应用评估。评估总是返回一个Boolean

我正在尝试专门使用 Java 流来输出这些数据。到目前为止,我已经能够使用 Java Streams 将.evaluate 应用于List&lt;BooleanExpression&gt; 列表中的每个BooleanExpression

return expressions.stream().map(e -> e.evaluate(context)).collect(Collectors.toList());

它工作正常并返回类似[true, true, false]

我现在要做的是使用stream().reduce 来连接该列表中的每个元素。如果我有[true, false, false] 的列表,我想以false 结尾。

这是我目前的代码:

return expressions.stream().reduce((x, y) -> x.evaluate(context) && y.evaluate(context));

它应该返回一个Boolean。但是,它给了我一个错误:

Java 流:无法从 Optional&lt;BooleanExpression&gt; 转换为 Boolean

我不确定我在这里做错了什么。谁能给点建议?

【问题讨论】:

    标签: java functional-programming java-stream boolean-logic


    【解决方案1】:

    The overload of reduce that you are using 返回一个Optional&lt;BooleanExpression&gt;,因为在空流的情况下,它可以返回Optional.empty(),表示没有什么可以减少。

    此外,该重载应该采用BinaryOperator&lt;BooleanExpression&gt;,您似乎没有给出它。你给它一个BiFunction&lt;BooleanExpression, BooleanExpression, Boolean&gt;。您使用的 lambda 接受两个布尔表达式并返回一个布尔值。

    解决这个问题。您可以先将所有内容映射到 booleans,然后使用 Boolean::logicalAnd 进行归约。如果流为空,您还需要指定要返回的默认值:

    return expressions.stream().map(x -> x.evaluate(context))
                               .reduce(Boolean::logicalAnd)
                               .orElse(true); // value to return if stream is empty
    

    或者,您可以使用接受 identity 元素的the other overload of reduce,并传入用于连接的身份 (true):

    return expressions.stream().map(x -> x.evaluate(context))
                               .reduce(true, Boolean::logicalAnd);
    

    如果流为空,这将返回 true。

    另一种方法是使用the third overload of reduce,它接受一个身份、一个BiFunction,以及一个组合器:

    return expressions.stream().reduce(
        true, 
        (x, y) -> x && y.evaluate(context),
        Boolean::logicalAnd);
    

    如果流为空,这将返回 true。

    【讨论】:

    • 非常感谢您的回复。我试图通过使用reduce来做到这一点,所以第三个选项看起来很有希望。但是,当我尝试这样做时,它会用The method evaluate(Map&lt;String,Boolean&gt;) is undefined for the type Boolean 突出显示x.evaluate。但是, y 似乎很好。奇怪。
    • @Zvonimir 哎呀!我犯了一个错误。查看编辑。
    • 效果很好!太棒了,非常感谢您的帮助!正是我想要的:)
    【解决方案2】:

    Reduce 返回一个可选项,因为可能没有任何结果。

    Optional<T> reduce(BinaryOperator<T> accumulator)
    

    如果您确定会产生某些东西,请尝试 return expressions.stream().reduce((x, y) -&gt; x.evaluate(context) &amp;&amp; y.evaluate(context)).get(); 或使用 Optional 运算符 .map 等。

    【讨论】:

    • 感谢您的回复。因此,由于某种原因,如果我添加 .get(),我会得到:Type mismatch: cannot convert from boolean to BooleanExpression。 :(
    • &amp;&amp; 计算为布尔值。
    • @Sweeper 感谢您的回复——是的,该方法返回一个布尔值。这就是为什么我现在很困惑。使用get() 会用Type mismatch: cannot convert from boolean to BooleanExpression 突出显示整个回报,而.orElse(true) 之类的东西只会突出显示x.evaluate(context) &amp;&amp; y.evaluate(context) 并出现相同的错误。此外,orElse(true) 有一个错误The method orElse(BooleanExpression) in the type Optional&lt;BooleanExpression&gt; is not applicable for the arguments (boolean)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-02
    • 2015-10-19
    • 2022-01-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多