Olga Gorun
Olga Gorun

Reputation: 327

How to get nested grouping for List with mapped values with Java 8 streams

I have a List and need convert it to nested (2 levels) map, where list is grouped by 2 different object properties and values should use third properties. Example:

[A("1","2","3"),A("1","2","4"),A("1","3","4"),A("2","3","5")]

should be converted to

{1={2=[3, 4], 3=[4]}, 2={3=[5]}}

Now to get this result I use the following construction:

    Map<String,Map<String,List<A>>> grouppedRecords = list.stream().collect(groupingBy(A::getA, groupingBy(A::getB)));

    Map<String,Map<String,List<String>>> results =  grouppedRecords.entrySet().stream().collect(Collectors.toMap(
            Map.Entry::getKey,
            e12 -> e12.getValue().entrySet().stream().collect(Collectors.toMap(
                    Map.Entry::getKey,
                    e22 -> e22.getValue().stream().map(A::getC).collect(Collectors.toList())
            )))
    );

But it looks over-complicated. Could you help me with a better way to sove the same problem?

Upvotes: 3

Views: 968

Answers (1)

Eran
Eran

Reputation: 393771

You can use Collectors.mapping to map the A instances to getC():

Map<String,Map<String,List<String>>> results = 
    list.stream()
        .collect(groupingBy(A::getA, 
                            groupingBy(A::getB,
                                       mapping(A::getC, toList()))));

Upvotes: 3

Related Questions