Combining Java 8 lambda predicates with logical operators
Solution 1
If there were a hypothetical Predicate.of
method, you could write:
stream.allMatch(Predicate.of(SomeClass::isFoo).or(SomeClass::isBar));
It doesn't exist, but you could write it yourself.
public final class Predicates {
public static <T> Predicate<T> of(Predicate<T> predicate) {
return predicate;
}
}
That said, I would personally go with your first option.
stream.allMatch(item -> item.isFoo() && item.isBar());
::
method references are nice but sometimes you have to write explicit lambdas.
Solution 2
This might not qualify as the answer (please don't up vote it if it does not), but I sort of had the same need, to munch together some predicates and I just wrote a small utility for that.
private static <T> Predicate<T> andPredicates(Predicate<T>... predicates) {
return Arrays.stream(predicates).reduce(Predicate::and).orElse(x -> true);
}
Solution 3
You could filter and only collect the size of the list and compare with the original list :
long count = list.stream().filter(SomeClass::isFoo).filter(SomeClass::isBar).collect(Collectors.counting());
lexicore
Please see my Xing profile if you want a business contact.
Updated on July 28, 2022Comments
-
lexicore over 1 year
I have a
Stream<SomeClass> stream
whereasSomeClass
has boolean methodsisFoo()
andisBar()
.I'd like to check that all elements in the stream have both
isFoo()
andisBar()
equals totrue
. I can check this conditions individually viaSomeClass:isFoo
andSomeClass::isBar
lambdas.But how would I combine these two lambdas with a logical operator like
and
/&&
?One obvious way is to write an extra lambda:
stream.allMatch(item -> item.isFoo() && item.isBar());
But I'd like to avoid writing an extra lambda.
Another way is to cast to
Predicate<? super SomeClass>
:stream.allMatch(((Predicate<? super SomeClass>) SomeClass::isFoo).and(SomeClass::isBar));
Is there a better way - without casts and explicit lambdas?
-
lexicore almost 7 yearsI don't need to select
isFoo()
andisBar()
elements, I need to check if all elements of the stream are bothisFoo()
andisBar()
. -
Andrea almost 7 yearsThen you could simply compare the size of the original list with the size of the filtered list, see my edit.
-
lexicore almost 7 yearsThis looks really suboptimal.
-
yiwei over 6 yearsI think this is a good answer. OP is looking to not combine lambdas with
&&
, but it's trivial to wrap the lambdas in aPredicate<T>
and then apply this answer. -
whiskeysierra over 5 yearsThis will fail if predicates is empty.
-
Eugene over 5 years@whiskeysierra good point! I guess
orElse
would suffice here