用于 if 条件的 Java Lambda 表达式 - 此处不期望

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23058864/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 20:22:17  来源:igfitidea点击:

Java Lambda Expression for if condition - not expected here

javajava-8lambda

提问by Patrick

Consider the case where an if condition needs to evaluate an array or a List. A simple example: check if all elements are true. But I'm looking for genericway to do it

考虑 if 条件需要评估数组或列表的情况。一个简单的例子:检查所有元素是否为真。但我正在寻找通用的方法来做到这一点

Normally I'd do it like that:

通常我会这样做:

boolean allTrue = true;
for (Boolean bool : bools){
    if (!bool) {
        allTrue = false;
        break;
     }
}
if (allTrue){
     // do Something
}

But now I'd like to hide it into my if condition. I tried using Lambda Expressions for this, but it's not working:

但现在我想把它隐藏在我的 if 条件中。我尝试为此使用 Lambda 表达式,但它不起作用:

if (() -> {
    for (Boolean bool : bools)
        if (!bool)
            return false;
    return true;
}){
      // do something
}

If this were working I could do something more complicated like

如果这行得通,我可以做一些更复杂的事情,比如

if (() -> {
   int number = 0;
   for (MyObject myobject : myobjects)
       if (myObject.getNumber() != 0)
           numbers++;
   if (numbers > 2) 
       return false;
   return true;
 }{
     //do something
 }

Is there a better way to do it is it just a syntax error?

有没有更好的方法来做它只是一个语法错误?

UPDATEI'm not talking about the boolean array, rather looking for a generic way to achieve that.

更新我不是在谈论布尔数组,而是在寻找实现这一目标的通用方法。

采纳答案by fge

You can write, given for instance a List<Boolean>:

你可以写,例如 a List<Boolean>

if (!list.stream().allMatch(x -> x)) {
    // not every member is true
}

Or:

或者:

if (list.stream().anyMatch(x -> !x)) {
    // at least one member is false
}

If you have an arrayof booleans, then use Arrays.stream()to obtain a stream out of it instead.

如果您有一个布尔数组,则使用它Arrays.stream()来获取流。



More generally, for a Streamproviding elements of (generic) type X, you have to provide a Predicate<? super X>to .{all,any}Match()(either a "full" predicate, or a lambda, or a method reference -- many things go). The return value of these methods are self explanatory -- I think.

更一般地,对于Stream提供 (generic) type 的元素X,您必须提供Predicate<? super X>to .{all,any}Match()(“完整”谓词,或 lambda,或方法引用 - 很多事情)。这些方法的返回值是不言自明的——我认为。



Now, to countelements which obey a certain predicate, you have .count(), which you can combine with .filter()-- which alsotakes (whatever is) a Predicateas an argument. For instance checking if you have more than 2 elements in a List<String>whose length is greater than 5 you'd do:

现在,要计算遵守某个谓词的元素,您有.count(),您可以将其与.filter()-结合使用- 它将(无论是什么) aPredicate作为参数。例如,检查 a 中是否有超过 2 个元素List<String>的长度大于 5,您会这样做:

if (list.stream().filter(s -> s.length() > 5).count() > 2L) {
    // Yup...
}

回答by Joffrey

Your problem

你的问题

Your current problem is that you use directly a lambda expression. Lambdas are instances of functional interfaces. Your lambda does not have the boolean type, that's why your ifdoes not accept it.

您当前的问题是您直接使用 lambda 表达式。Lambda 是函数式接口的实例。您的 lambda 没有 boolean 类型,这就是您if不接受它的原因

This special case's solution

这种特殊情况的解决方案

You can use a stream from your collections of booleans here.

您可以在此处使用布尔值集合中的流。

if (bools.stream().allMatch((Boolean b)->b)) {
    // do something
}

It is actually much more powerful than this, but this does the trick I believe.

它实际上比这强大得多,但我相信这是诀窍。

General hint

一般提示

Basically, since you want an ifcondition, you want a booleanresult. Since your result depends on a collection, you can use Java 8 streams on collections.

基本上,既然你想要一个if条件,你就想要一个boolean结果。由于您的结果取决于集合,因此您可以在集合上使用 Java 8 流。

Java 8 streams allow you to do many operations on a collection, and finish with a terminal operation. You can do whatever complicated stuff you want with Stream's non-terminal operations. In the end you need one of 2 things:

Java 8 流允许您对集合执行许多操作,并以终端操作结束。你可以用Stream的非终端操作做任何你想做的复杂的事情。最后,您需要两件事之一:

  • use a terminal operation that returns a boolean(such as allMatch, anyMatch...), and you're done
  • use any terminal operation, but use it in a booleanexpression, such as myStream.filter(...).limit(...).count() > 2
  • 使用返回a boolean(例如allMatchanyMatch...)的终端操作,您就完成了
  • 使用任何终端操作,但在boolean表达式中使用它,例如myStream.filter(...).limit(...).count() > 2

You should have a look at your possibilities in this Stream documentationor this one.

您应该在此 Stream 文档文档中查看您的可能性。