Skip to content
Advertisement

Java-Stream – Grouping Lists based on several elements within each List

I have the following data stored as lists:

List<ArrayList<String>> dummy = new ArrayList<>();
dummy.add(new ArrayList<>(List.of("1", "SP1", "SW1")));
dummy.add(new ArrayList<>(List.of("2", "SP1", "SW2")));
dummy.add(new ArrayList<>(List.of("3", "SP2", "SW1")));
dummy.add(new ArrayList<>(List.of("4", "SP2", "SW2")));
dummy.add(new ArrayList<>(List.of("5", "SP2", "SW1")));
dummy.add(new ArrayList<>(List.of("6", "SP1", "SW1")));
dummy.add(new ArrayList<>(List.of("7", "SP3", "SW2")));

I need to group it as follows

SW1-SP1-list{1,6}  
SW1-SP2-list{3,5}  
SW2-SP1-list{2}   
SW2-SP2-list{4}    
SW2-SP3-list{7}

What I have tried is the following:

var test = dummy.stream()
    .collect(Collectors.groupingBy(
        s -> s.get(2),
        TreeMap::new,
        Collectors.groupingBy(
            s -> s.get(1),
            Collectors.toList()
        )
    ));

But this doesn’t give the desired result.

Advertisement

Answer

Here’s how you can apply nested groupingBy

Map<String, Map<String, List<String>>> result = dummy.stream()
        .collect(Collectors.groupingBy(l -> l.get(2),
                Collectors.groupingBy(l -> l.get(1),
                        Collectors.mapping(l -> l.get(0), Collectors.toList()))));

To collect it in the order encountered, you can use a LinkedHashMap,

Map<String, Map<String, List<String>>> result = dummy.stream()
        .collect(Collectors.groupingBy(l -> l.get(2), LinkedHashMap::new,
                Collectors.groupingBy(l -> l.get(1), LinkedHashMap::new,
                        Collectors.mapping(l -> l.get(0), Collectors.toList()))));
System.out.println(result);

Result:

{SW1={SP1=[1, 6], SP2=[3, 5]}, SW2={SP1=[2], SP2=[4], SP3=[7]}}
User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement