Java Lambda表达式用于if条件-不应在此处使用

4
考虑需要评估数组或列表的if条件的情况。一个简单的例子:检查所有元素是否为true。但我正在寻找一种通用的方法来实现它。
通常我会这样做:
boolean allTrue = true;
for (Boolean bool : bools){
    if (!bool) {
        allTrue = false;
        break;
     }
}
if (allTrue){
     // do Something
}

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

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

如果这个工作正常运行,我可以做更复杂的事情,比如:
if (() -> {
   int number = 0;
   for (MyObject myobject : myobjects)
       if (myObject.getNumber() != 0)
           numbers++;
   if (numbers > 2) 
       return false;
   return true;
 }{
     //do something
 }

有没有更好的方法来做这件事,还是只是语法错误?

更新:我不是在谈论布尔数组,而是寻找一种通用的方法来实现它。


2
.anyMatch() 吗? - fge
1
@fge .allMatch() 可能是吗?他想要在所有都为 true 时返回 true。 - Marco Acierno
谢谢,我不了解那些函数。实际上我在寻找一种通用的方法去做它,可能表述不清楚。 - Patrick
哦,你的问题编辑使得事情非常不清楚 -- 你需要什么?一定谓词匹配的元素计数吗? - fge
4
一个@FunctionalInterface虽然有些会返回布尔值,但它并不是一个布尔类型;你必须调用该“接口”才能得到布尔结果。 - fge
显示剩余3条评论
2个回答

13

你可以编写,例如给定一个 List<Boolean>

if (!list.stream().allMatch(x -> x)) {
    // not every member is true
}
或者:
if (list.stream().anyMatch(x -> !x)) {
    // at least one member is false
}
如果你有一个布尔类型的数组,那么可以使用 Arrays.stream() 来获取它的流。
更普遍的情况是,对于提供 (泛型) 类型为 X 的元素的流 Stream,你必须提供一个 Predicate<? super X>.{all,any}Match()(这个谓词可以是一个完整的谓词、一个 lambda 表达式或者一个方法引用 -- 诸多选择)。这些方法的返回值是自我解释的。
现在,如果你要计算遵守某个谓词的元素数目,你可以使用 .count(),并将其与 .filter() 结合使用 -- 后者同样需要一个(任何) 谓词作为参数。例如,检查 List<String> 中长度大于 5 的元素是否超过 2 个,可以这样做:
if (list.stream().filter(s -> s.length() > 5).count() > 2L) {
    // Yup...
}

4

你的问题

你目前的问题是直接使用了一个lambda表达式。Lambda表达式是函数式接口的实例。你的lambda表达式没有布尔类型,这就是为什么你的if不接受它的原因

这种特殊情况的解决方案

在这里,你可以使用一个从布尔集合中创建的流。

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

实际上,它比这个更强大,但我相信这已经足够了。

一般提示

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

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

  • 使用返回boolean的终端操作(例如allMatchanyMatch ...)即可完成
  • 使用任何终端操作,但在boolean表达式中使用它,例如myStream.filter(...).limit(...).count() > 2

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


这对我来说会产生语法错误:不兼容的类型:无法推断出Predicate <? super boolean []>的功能接口描述符。 - Ghostkeeper

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接