繁体   English   中英

将Java 8 lambda谓词与逻辑运算符组合在一起

[英]Combining Java 8 lambda predicates with logical operators

我有一个Stream<SomeClass> streamSomeClass有布尔方法isFoo()isBar()

我想检查流中的所有元素是否同时具有isFoo()isBar()等于true 我可以通过SomeClass:isFoo单独检查这个条件SomeClass:isFooSomeClass::isBar lambdas。

但是我如何将这两个lambdas与逻辑运算符and / &&结合起来呢?

一个明显的方法是写一个额外的lambda:

stream.allMatch(item -> item.isFoo() && item.isBar());

但是我想避免写一个额外的lambda。

另一种方法是投射到Predicate<? super SomeClass> Predicate<? super SomeClass>

stream.allMatch(((Predicate<? super SomeClass>) SomeClass::isFoo).and(SomeClass::isBar));

有没有更好的方法 - 没有演员表和明确的lambdas?

如果有一个假设的Predicate.of方法,你可以写:

stream.allMatch(Predicate.of(SomeClass::isFoo).or(SomeClass::isBar));

它不存在,但您可以自己编写。

public final class Predicates {
    public static <T> Predicate<T> of(Predicate<T> predicate) {
        return predicate;
    }
}

也就是说,我个人会选择你的第一个选择。

stream.allMatch(item -> item.isFoo() && item.isBar());

::方法引用很好但有时你必须编写显式的lambdas。

这也许不能算作答案(请如果不这样做不起来投票吧),但我有点有同样的需要,咀嚼一些谓词在一起,我只是写了一个小程序来达到这个。

private static <T> Predicate<T> andPredicates(Predicate<T>... predicates) {
    return Arrays.stream(predicates).reduce(Predicate::and).orElse(x -> true);
}

您可以过滤并仅收集列表的大小并与原始列表进行比较:

long count = list.stream().filter(SomeClass::isFoo).filter(SomeClass::isBar).collect(Collectors.counting());

你绝对应该使用Stream的过滤方法。 过滤器选择与给定谓词匹配的列表元素。

此行同时选择Foo和Bar的元素:

list.stream().filter(SomeClass::isFoo).filter(SomeClass::isBar)

输出是一个Stream,因此您应该收集List中的元素以实际使用它们:

 list.stream().filter(SomeClass::isFoo).filter(SomeClass::isBar).collect(Collectors.toList());

为了检查流的所有元素是否都是Foo和Bar,您可以将原始列表的大小与过滤流的大小进行比较:

public static Boolean isFooBar(List<SomeClass> list) {
    return list.size() == list.stream().filter(SomeClass::isFoo).filter(SomeClass::isBar).count();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM