Stream GroupingBy for an Object Inside another Different Object

I have three Objects as below :

public class A {
     private int a;
     private ...
     private B b;
    //getters setters for B
}

public class B {
     private String name;
     private ... 
     private C c;
    //getters setters for C
}

public class C {
     private Long id;
     private ... 
}

I'm having a List<A> with B's Object in every A and C's Object In every B.

I want to group A list by C.id in a map Map<C,List<A>>

How do I achieve this using groupingBy method of Stream?

1 answer

  • answered 2018-03-11 13:33 Aominè

    Map<Long, List<A>> resultSet = 
           myList.stream()
                 .collect(Collectors.groupingBy(e -> e.getB().getC().getId()));
    

    edit:

    Since you want a Map<C, List<A>> as the receiver type of the result set then you'll need to override equals and hashcode in your C class like this:

    class C {
         public Long getId() {
             return id;
         }
    
         @Override
         public boolean equals(Object o) {
             if (this == o) return true;
             if (o == null || getClass() != o.getClass()) return false;
    
             C c = (C) o;
    
             return id != null ? id.equals(c.id) : c.id == null;
         }
    
         @Override
         public int hashCode() {
             return id != null ? id.hashCode() : 0;
         }
    
         private Long id;
    }
    

    Now, you can do:

    Map<C,List<A>> resultSet = 
         myList.stream()
               .collect(Collectors.groupingBy(e -> e.getB().getC()));
    

    This means all A objects that have the same C.id will be in the same bucket (i.e group).