ealeon
ealeon

Reputation: 12452

java: reduce vs anyMatch vs contains

 List<Boolean> results = new ArrayList<>();
 results.add(true);
 results.add(true);
 results.add(true);
 results.add(false);

 if (results.contains(false)) {
     System.out.println(false);
 } else {
     System.out.println(true);
 }

 System.out.println(results.stream().reduce((a, b) -> a && b).get());
 //System.out.println(!results.stream().anyMatch(a -> a == false));
 System.out.println(!results.stream().anyMatch(a -> !a));

OUTPUT:
false
false
false

FYI, the results are a result of a map+collect op

List<Job> jobs;
List<Boolean> results = job.stream().map(j -> j.ready()).collect(Collector.toList())

If I choose either reduce or anyMatch, I don't have to collect the results from map operation.

From results which is a list of boolean, I just want to return false if there is at least one false.

I can do it via reduce or anyMatch. I kinda don't like Optional from reduce, and I kinda don't like that I have to negate anyMatch

Are there any pros/cons for using either?

Upvotes: 7

Views: 4745

Answers (3)

Vishwa Ratna
Vishwa Ratna

Reputation: 6390

 System.out.println(results.stream().reduce((a, b) -> a && b).get());

This will always return false, as the list(results) has at-least 1 false.

&& will always check for both value to be true to pass it as true.

 System.out.println(!results.stream().anyMatch(a -> !a));

Stream anyMatch(Predicate predicate) returns whether any elements of this stream(results) match the provided predicate(a -> !a). As you are doing !results so the result will come-out to be false at last after initial true.

Upvotes: 0

Misha
Misha

Reputation: 28133

It appears that the only reason you are collecting the booleans into the list is so you can check if some are false:

If I choose either reduce or anyMatch, I don't have to collect the results from map operation [...] I just want to return false if there is at least one false.

If this is the case, then you definitely should consider the straightforward stream-based approach:

return jobs.stream().allMatch(Job::ready);

Upvotes: 7

Al Kepp
Al Kepp

Reputation: 5980

You ask pros/cons. Contains is the fastest and simplest. Reduce is the most cumbersome/complicated here. But your task is very simple, so does it really matter? Maybe the better key to select which approach to use would be: "Which one is better readable, understandable and maintainable?" This clean-code approach is usually more important in practical software development than hunting microseconds in runtime or number of lines in source code. But then again I would say contains is the best here.

System.out.println(!results.contains(false));

Then your anyMatch(a -> !a) is effectively the same as contains and I would definitely prefer it over reduce for this concrete task. But again, real difference is very small and I would more concern the readability and understandability for a future maintainer of this software.

Upvotes: 2

Related Questions