Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to filter collection based on property within double nested list using Java streams

I am in the process of trying to better understand how to use Java streams. I have these classes:

public class Plan {

    List<Request> requestList;
}

public class Request {

    List<Identity> identityList;
    boolean isCancelled;

}

public class Identity {

    String idNumber;
}

I am trying to write a method that returns the plan that contains the non-cancelled request with a matching identity number.

This is what I have tried:

public static Plan findMatchingPlan(List<Plan> plans, String id) {
    List<Plan> filteredPlan = plans.stream()
            .filter(plan -> plan.getRequestList().stream()
                    .filter(request -> !request.isCancelled())
                    .filter(request -> request.getIdentityList().stream()
                        .filter(identity -> identity.getIdNumber().equals(id))))
            .collect(Collectors.toList());
}

This gives me an error:

java.util.stream.Stream<com.sandbox.Identity> cannot be converted to boolean

I sort of understand why there is an error. The nested filter returns a filter that cannot be evaluated as a boolean. The problem is, I don't know what I am missing.

Any help would be appreciated.

like image 272
Seephor Avatar asked Apr 26 '18 22:04

Seephor


1 Answers

Assuming you want first matching Plan, it can be done like this, using lambda expressions:

public static Plan findMatchingPlan(List<Plan> plans, String id) {
    return plans.stream()
                .filter(plan -> plan.getRequestList()
                                    .stream()
                                    .filter(request -> ! request.isCancelled())
                                    .flatMap(request -> request.getIdentityList().stream())
                                    .anyMatch(identity -> identity.getIdNumber().equals(id)))
                .findFirst()
                .orElse(null);
}

Or like this, using method references, and finding any matching Plan:

public static Plan findMatchingPlan(List<Plan> plans, String id) {
    return plans.stream()
                .filter(plan -> plan.getRequestList()
                                    .stream()
                                    .filter(request -> ! request.isCancelled())
                                    .map(Request::getIdentityList)
                                    .flatMap(List::stream)
                                    .map(Identity::getIdNumber)
                                    .anyMatch(id::equals))
                .findAny()
                .orElse(null);
}
like image 161
Andreas Avatar answered Nov 14 '22 10:11

Andreas