用于if条件的Java Lambda表达式 - 此处不需要

时间:2014-04-14 11:26:54

标签: java java-8 lambda

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

通常我会这样做:

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

但现在我想把它隐藏到我的if条件中。我尝试使用Lambda Expressions,但它不起作用:

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 个答案:

答案 0 :(得分:12)

您可以编写,例如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()来获取其中的流。


更一般地说,对于Stream提供(通用)类型X的元素,您必须提供Predicate<? super X>.{all,any}Match()(“完整”谓词,或lambda,或方法参考 - 许多事情都去了)。这些方法的返回值是不言自明的 - 我认为。


现在,要计数符合某个谓词的元素,您有.count(),可以与.filter()结合使用 - Predicate作为参数取(以及)。例如,检查List<String>中是否有超过2个元素,其长度大于5:

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

答案 1 :(得分:4)

您的问题

您当前的问题是您直接使用lambda表达式。 Lambdas是功能接口的实例。你的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

您应该在this Stream documentationthis one中查看您的可能性。