簡體   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