Search code examples
javajava-streamnested-lists

How to return an object property that matches conditions in a List<ObjectA> of List<ObjectB> (nested list) in java?


I am trying to return an object property (or the object) efficiently in a List of lists. Lets call my initial object MasterObject.
MasterObject has List<ObjectA> where ObjectA has List<ObjectB> that has property ObjectC.

ObjectC has multiple properties that I want to match (e.g. String type, int length) and I want to return property String propertyID of ObjectC or return the ObjectC itself (if a matching object exists).

I was able to determine whether such element exists using streams anymatch.

MasterObject.getListObjectA.stream()
    .anymatch(x -> x !=null && x.getListOjectB.stream().anymatch(y -> y.getObjectC().getType().equals("rf") && y.getObjectC().getLength() == 3));

Now I want to get a reference to the ObjectC or ObjectB so I can return ObjectB.getObjectC.ID.

Can this be achieved with streams?

Tips and help is greatly appreciated!


Solution

  • You can use Stream#flatMap to flatten the nested stream along with filter to filter an ObjectC instance matching the condition. We can use findFirst to find a (any) matching ObjectC.

     Optional<String> optionalPropertyId = objectAs.stream()
                .filter(Objects::nonNull)
                .flatMap(objectA -> objectA.getListObjectB().stream())
                .filter(objectB -> objectB.getObjectC().getType().equals("rf")
                        && objectB.getObjectC().getLength() == 3)
                .map(objectB -> objectB.getObjectC().getPropertyID())
                .findFirst();
    

    The flatMap returns Stream<ObjectB> and the filter on this is same as your existing condition/check. If the check passes, it uses map to extract the propertyID of the ObjectC.

    Note that the result is an Optional and could be empty if no ObjectC instances exist which match the passed predicate.