Search code examples
javalambdajava-8java-stream

Java 8 filter list of pojos based on nested object attribute


I have a list of Thingy pojos, such that:

public class Thingy {
    private DifferentThingy nestedThingy;
    public DifferentThingy getNestedThingy() {
        return this.nestedThingy;
    }
}

...

public class DifferentThingy {
    private String attr;
    public String getAttr() {
        return this.attr;
    }
}

I want to filter a

List<Thingy>

to be unique based on the

attr

of the Thingy's

DifferentThingy

Here is what I have tried so far:

private List<Thingy> getUniqueBasedOnDifferentThingyAttr(List<Thingy> originalList) {
    List<Thingy> uniqueItems = new ArrayList<Thingy>();
    Set<String> encounteredNestedDiffThingyAttrs= new HashSet<String>();
    for (Thingy t: originalList) {
        String nestedDiffThingyAttr = t.getNestedThingy().getAttr();
        if(!encounteredNestedDiffThingyAttrs.contains(nestedDiffThingyAttr)) {
            encounteredNestedDiffThingyAttrs.add(nestedDiffThingyAttr);
            uniqueItems.add(t);
        }
    }
    return uniqueItems;
}

I want to do this using a Java 8 stream and lambdas for the two getters that end up retrieving the attribute used for determining uniqueness, but am unsure how. I know how to do it when the attribute for comparison is on the top level of the pojo, but not when the attribute is nested in another object.


Solution

  • You can do it that way:

    originalList.stream()
        .collect(Collectors.toMap(thing -> thing.getNestedThingy().getAttr(), p -> p, (p, q) -> p))
        .values();
    

    Not sure if the most optimal way though, I'm on Android, so don't use streams in daily job.

    UPD

    For someone can not compile it, there is full code of my test file.