singe3
singe3

Reputation: 2105

Stream grouping : children list to unique parent list

I'm looking for a concise and efficient way to get a list of unique parents from a list of children using Java 8 streams.

For the example I have these two simple classes :

public class Child{
  private Parent parent;
  public Child(Parent parent){
    this.parent = parent;
  }
  public Parent getParent(){
    return this.parent;
  }
}

public class Parent{
  private List<Child> children;
  public Parent(){
    this.children = new ArrayList<Child>();
  }
  public void addChild(Child child){
    this.children.add(child);
  }
}

First I get a list of Child object from some method.
The children may belong to multiple parents with possible parents collisions.

List<Child> children = getChildren();

Then :

List<Parent> uniqueParents = children
  .stream()
  .collect(Collectors.groupingBy(Child::getParent))
  .keySet()
  .stream()
  .collect(Collectors.toList());

So it works, but I'd like to avoid the double stream and collect.

Is this possible directly in one stream ?

Upvotes: 0

Views: 1979

Answers (3)

S&#225;ndor Juhos
S&#225;ndor Juhos

Reputation: 1615

You should try this

public Set<Parent> getUniqueParents() {
  return children.stream()
                 .map(child -> child.getParent())
                 .collect(Collectors.toSet());
}

Upvotes: 2

Thomas Kl&#228;ger
Thomas Kl&#228;ger

Reputation: 21435

How about this:

List<Parent> uniqueParents = children
    .stream()
    .map(Child::getParent)
    .distinct()
    .collect(Collectors.toList());

Upvotes: 6

why_vincent
why_vincent

Reputation: 2262

How about this?

    Set<Parent> parents = new TreeSet<>();
    children.forEach(c -> parents.add(c.getParent()));

It is without streams but should solve the problem if you make sure to implement comparable. Could of course also use HashSet if you implement equals and hashcode.

Upvotes: 0

Related Questions