I have a List of Maps which stores the roles and the names of people. For ex:
List<Map<String, String>> listOfData
1) Role: Batsman
Name: Player1
2)Role: Batsman
Name: Player2
3)Role: Bowler
Name: Player3
Role and Name are the Keys of the map.
I want to convert this into a Map<String, List<String>> result
, which will give me a list of names for each role, i.e
k1: Batsman v1: [Player1, Player2]
k2: Bowler v2: [Player3]
listOfData
.stream()
.map(entry -> new AbstractMap.SimpleEntry<>(entry.get("Role"), entry.get("Name"))
.collect(Collectors.toList());
Doing this way will not give me a list of names for the role, it will give me a single name. How do i keep collecting the elements of the list and then add it to a key ?
Java code to create base structure:
Map<String, String> x1 = ImmutableMap.of("Role", "Batsman", "Name", "Player1");
Map<String, String> y1 = ImmutableMap.of("Role", "Batsman", "Name", "Player2");
Map<String, String> z1 = ImmutableMap.of("Role", "Bowler", "Name", "Player3");
List<Map<String, String>> list = ImmutableList.of(x1, y1, z1);
Map<String, List<String>> z = list.stream()
.flatMap(e -> e.entrySet().stream())
.collect(Collectors.groupingBy(Map.Entry::getKey,
Collectors.mapping(Map.Entry::getValue, Collectors.toList())));
With Java 8, you can convert a List to Map in one line using the stream() and Collectors. toMap() utility methods. The Collectors. toMap() method collects a stream as a Map and uses its arguments to decide what key/value to use.
Method 1: Using Collectors.toMap() Function The Collectors. toMap() method takes two parameters as the input: KeyMapper: This function is used for extracting keys of the Map from stream value. ValueMapper: This function used for extracting the values of the map for the given key.
Converting a list to stream is very simple. As List extends the Collection interface, we can use the Collection. stream() method that returns a sequential stream of elements in the list.
listOfData.stream()
.flatMap(e -> e.entrySet().stream())
.collect(Collectors.groupingBy(Map.Entry::getKey,
Collectors.mapping(Map.Entry::getValue,
Collectors.toList())));
update:
Slightly different variant to user1692342
's answer for completeness.
list.stream()
.map(e -> Arrays.asList(e.get("Role"), e.get("Name")))
.collect(Collectors.groupingBy(e -> e.get(0),
Collectors.mapping(e -> e.get(1), Collectors.toList())));
Based on the idea given by Aomine:
list.stream()
.map(e -> new AbstractMap.SimpleEntry<>(e.get("Role"), e.get("Name")))
.collect(Collectors.groupingBy(Map.Entry::getKey,
Collectors.mapping(Map.Entry::getValue, Collectors.toList())));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With