I want to find out which element is failing the predicate in case of allmatch
.
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
boolean isEven = numbers.stream().allMatch(n-> n % 2 == 0);
Here isEven
is false
, as element 1
fails the predicate.
I can use forEach
over the stream to find which element fails like:
numbers.stream().forEach(n -> {
if (n % 2 != 0)
System.out.println(n + "is Odd");
});
Is there a way to figure out which elements fails the predicate in the allmatch
when it returns false
?
To find an element matching specific criteria in a given list, we: invoke stream() on the list. call the filter() method with a proper Predicate. call the findAny() construct, which returns the first element that matches the filter predicate wrapped in an Optional if such an element exists.
Stream allMatch(Predicate predicate) returns whether all elements of this stream match the provided predicate. It may not evaluate the predicate on all elements if not necessary for determining the result. This is a short-circuiting terminal operation.
The findFirst() method finds the first element in a Stream. So, we use this method when we specifically want the first element from a sequence. When there is no encounter order, it returns any element from the Stream.
The difference is in the type of the return value: Stream#findAny() : Returns an Optional describing some element of the stream, or an empty Optional if the stream is empty. Returns an Optional describing the first element of this stream, or an empty Optional if the stream is empty.
Please remember that allMatch
is a short-circuiting operation, meaning that the stream API may return false without finding all the elements that fail the test.
So if you want to find all the failing elements, you might have to do more work than a simple allMatch
(as shown by other answers). However, if you only care to find one element that fails the test, use findAny
as follows:
Optional<Integer> odd = numbers.stream()
.filter(n -> n % 2 != 0)
.findAny();
boolean isEven = !odd.isPresent();
odd.ifPresent(x -> System.out.println(x + " is odd"));
For this example:
Map<Boolean, List<Integer>> map = numbers.stream()
.collect(Collectors.partitioningBy(x -> x % 2 == 0));
System.out.println(map); // {false=[1, 3, 5], true=[2, 4]}
You could simply log it for example also:
boolean isEven = numbers.stream().allMatch(n -> {
boolean test = n % 2 == 0;
if (!test) {
System.out.println("Failed = " + n);
}
return test;
});
But this might introduce interesting results if you run it in parallel
. The output would be un-predictable. That is isEven
is still going to return the correct result, but what you see via Syso
is completely un-predicatable. Could be :
Failed = 3
Failed = 1
Failed = 5
And on another run could be:
Failed = 3
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With