I have the following data stored as lists:
JavaScript
x
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
JavaScript
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:
JavaScript
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
JavaScript
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
,
JavaScript
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:
JavaScript
{SW1={SP1=[1, 6], SP2=[3, 5]}, SW2={SP1=[2], SP2=[4], SP3=[7]}}