List of Java 8 filters from pojos based on attribute of nested object

I have a list of Thingy pojos, for example:

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

List<Thingy>

to be unique based

attr

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 thread and lambdas for two getters that eventually retrieve the attribute used to determine uniqueness, but I'm not sure how to do this. I know how to do this when the comparison attribute is at the top level of the pojo, but not when the attribute is nested in another object.

+4
source share
5 answers

You can do it as follows:

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

, , , Android, .

UPD

- , .

+4

, javaslang

javaslang.collection.List.ofAll(thingies)
  .distinctBy(t -> t.getNestedThingy().getAttr());

Javaslang core - Java 8+. . . Javaslang . .

+4

. . "", , . , , Thingy NestedThingy . , :

public class Thingies {

    public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        final Set<Object> seen = Collections.synchronizedSet(new HashSet<>());
        return t -> seen.add(keyExtractor.apply(t));
    }

    private static List<Thingy> getUniqueBasedOnDifferentThingyAttr(List<Thingy> originalList) {
        return originalList.stream()
                .filter(distinctByKey(thingy -> thingy.getNestedThingy().getAttr()))
                .collect(toList());
    }

    public static void main(String[] args) {
        List<Thingy> originalList = new ArrayList<>();
        originalList.add(new Thingy(new DifferentThingy("first")));
        originalList.add(new Thingy(new DifferentThingy("first")));
        originalList.add(new Thingy(new DifferentThingy("second")));
        System.out.println(getUniqueBasedOnDifferentThingyAttr(originalList));
    }
}

:

[first, second]

, OP ( ), :

private static List<Thingy> getUniqueBasedOnDifferentThingyAttr(List<Thingy> originalList) {
    final Set<String> uniqueAttributes = new HashSet<>(originalList.size());
    return originalList.stream()
            .filter(thingy -> {
                int initialSize = uniqueAttributes.size();
                uniqueAttributes.add(thingy.getNestedThingy().getAttr());
                return initialSize != uniqueAttributes.size();
            }).collect(toList());
}
+2

TreeSet, :

private static List<Thingy> getUniqueBasedOnDifferentThingyAttr(List<Thingy> originalList) {

    Set<Thingy> uniqueSet = new TreeSet<Thingy>(Comparator.comparing(thingy -> thingy.getNestedThingy().getAttr()));

    return originalList.stream()
            .filter(uniqueSet::add)
            .collect(Collectors.toList());
}

uniqueSet::add , true, .

+2

StreamEx:

StreamEx.of(originalList).distinct(e -> e.getNestedThingy().getAttr()).toList();

Or AbacusUtil

Stream.of(originalList).distinct(e -> e.getNestedThingy().getAttr()).toList();
0
source

Source: https://habr.com/ru/post/1670335/


All Articles