[英]Combining Java 8 lambda predicates with logical operators
我有一個Stream<SomeClass> stream
而SomeClass
有布爾方法isFoo()
和isBar()
。
我想檢查流中的所有元素是否同時具有isFoo()
和isBar()
等於true
。 我可以通過SomeClass:isFoo
單獨檢查這個條件SomeClass:isFoo
和SomeClass::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.