如何使用 Stream IPA 确定 Collection 中的所有元素是否具有相同的值

How to determine whether all elements in a Collection have the same value with Stream IPA

我正在尝试根据 collection 有匹配的 boolean 属性.

我做了一个简单的例子,其中 'falseList' returns false.

所以我的问题是,是否有一个流调用来干净地检查集合中匹配的 boolean 值,这样 'falseList' 将导致 true 因为所有属性都匹配?

我知道我可以获取集合中的第一项,然后将所有值与 2 行中 allMatch() 的第一项进行比较,但是我正在寻找单行出于好奇。

class BooleanClass {
    boolean val;

    public BooleanClass(boolean val) {
        this.val = val; 
    }

    public boolean getVal() {
        return this.val;
    }
}

public class AllMatch {
    
    public static void main(String[] args) {
        BooleanClass a = new BooleanClass(true);
        BooleanClass b = new BooleanClass(true);
        BooleanClass c = new BooleanClass(true);

        ArrayList<BooleanClass> trueList = new ArrayList<BooleanClass>();
        trueList.add(a);
        trueList.add(b);
        trueList.add(c);

        System.out.println(trueList.stream().allMatch(l -> l.getVal())); // true

        BooleanClass d = new BooleanClass(false);
        BooleanClass e = new BooleanClass(false);
        BooleanClass f = new BooleanClass(false);

        ArrayList<BooleanClass> falseList = new ArrayList<BooleanClass>();
        falseList.add(d);
        falseList.add(e);
        falseList.add(f);

        System.out.println(falseList.stream().allMatch(l -> l.getVal())); // false
    }
}

当前输出:

true
false

期望输出:

true
true

首先,您的问题提到了 allMatch,但是,您在代码中使用了 anyMatch。无论哪种方式,对于要计算为 true 的东西,lambda 应该计算为 true。在您的例子中,第一个表达式 l -> l.getVal() 的计算结果总是 true。对于第二个表达式 l -> l.getVal() 总是计算为 false,因此有效结果将是 false。要使其成为 true,您必须将 lambda 更改为 l -> l.getVal() == false。不确定这是否是您想要实现的目标。

return true or false based on if every item in the collection has a matching boolean property

因此您需要检查 list 中的所有元素是否具有相同的值(所有 true 或所有 false)。并且您想在 单流语句 .

中实现这一点

你可以用 anyMatch() 来完成。使用此操作检查 allMatch() 的优势在于 anyMatch()short-circuit 操作。 IE。当它遇到与给定的 predicate 不匹配的元素时,它会终止流 pipe-line 和 return 结果的执行。

它可能看起来像:

public static boolean isNonUniform(Collection<Boolean> list) {
    return list.stream().anyMatch(el -> el.getVal() != falseList.get(0).getVal());
}

方法isNonUniform()顾名思义,如何从谓词传递给anyMatch(),检查给定集合是否包含至少一个与其他元素不同的元素。

注意,访问列表的第一个元素是安全的,因为如果列表为空, predicate 将不会被评估。

另请注意,当流中没有元素时,anyMatch() 将 return false。 IE。空列表被认为是统一的(不是非统一的)。如果你想在列表为空时获得true,那么在流的前面附加这个条件:falseList.isEmpty() ||。从技术上讲,它仍然是 one-liner.

所以为了判断列表是否统一,应该这样使用:

System.out.println(!isNonUniform(falseList));

Side-note:我个人认为方法名中有notnon不是perfect) 从 clean-coding 的角度来看是较小的邪恶,然后将逻辑非 ! 放在流的前面,这使得它更难阅读。