0

I have a list of map of string string(List<Map<String,String>>) like bellow,

[{key = "car", value = "bmw"},{key = "car", value = "suzuki"},{key = "car", value = "hyundai"},{key = "bike", value = "honda"},{key = "bike", value = "tvs"}]

I want to convert to below list of map string list string(List<Map<String, List<String>>>) or something equal

[{key = "car", value = ["bmw","suzuki","hyundai"]},{key = "bike", value = ["honda","tvs"]}]

Thanks in advance.

2
  • How do you populate the List currently? Maybe sharing some code examples would be useful. Commented May 12, 2020 at 16:46
  • It is just enough with Map<String, List<String>>, you don't need to put it in a list anymore Commented May 12, 2020 at 17:09

2 Answers 2

2

Java 8+

For singleton maps

Use groupingBy to separate by key and then mapping to get the value of your singleton map

Map<String, List<String>> res = 
  list.stream()
    .map(map -> map.entrySet().iterator().next())
    .collect(Collectors.groupingBy(
      entry -> entry.getKey(),
      Collectors.mapping(
        entry -> entry.getValue(), 
        Collectors.toList()
      )
    )
  );

For maps with multiple entries

You do the same as above, but flatMap to get all the entries in a single 1-D stream

Map<String, List<String>> res = 
  list.stream()
    .flatMap(map -> map.entrySet().stream())
    .collect(Collectors.groupingBy(
      entry -> entry.getKey(),
      Collectors.mapping(
        entry -> entry.getValue(), 
        Collectors.toList()
      )
    )
  );

Pre-Java 8

For maps with multiple entries

You'll have to iterate through each map in the list, and then through the entries of each map. For each entry, check if the key's already there, and if so, add the value to the list associated with that key. If the key's not in the result map, then create a new list there.

Map<String, List<String>> map = new HashMap<>();
for (Map<String, String> m : list) {
  for (Map.Entry<String, String> e : m.entrySet()) {
    String key = e.getKey();
    if (!map.containsKey(key)) {
      map.put(key, new ArrayList<String>());
    }
    map.get(key).add(e.getValue());
  }
}

For singleton maps

For each map in your original list, you find the first entry, and then you do the same as above: add that entry's value to the list that the entry's key maps to, and before that, add a new List to the map if the key doesn't exist there already.

Map<String, List<String>> map = new HashMap<>();
for (Map<String, String> m : list) {
  Map.Entry<String, String> e = m.entrySet().iterator().next();
  String key = e.getKey();
  if (!map.containsKey(key)) {
    map.put(key, new ArrayList<String>());
  }
  map.get(key).add(e.getValue());
}
Sign up to request clarification or add additional context in comments.

8 Comments

i am using openjdk version "1.8.0_242". Which above code is not supported. while i am using like this "import java.util.stream.Collectors;". Please help
Yes... First I did the same
Can't import collectors... Version not supported.
Didn't try that. Will update after trying that .. really thanks for reply and help
I am using java 7. stream.Collectors is not been supported. is there any way without using collectors ?
|
0

Based on your example, you have a list of maps like this:

List<Map<String,String>> myListOfMaps = List.of(
        Map.of("car", "bmw"),
        Map.of("car", "suzuki"),
        Map.of("car", "hyundai"),
        Map.of("bike", "honda"),
        Map.of("bike", "tvs")                        
);

Then you can use the groupingBy function of streams to do something similar to what you see below.

Stream your list, flatten the stream by streaming over the entrysets, group the entrysets by their keys, map to a list of values

Map<String,List<String>> myResultMap = myListOfMaps.stream()
        .flatMap(m -> m.entrySet().stream())
        .collect(Collectors.groupingBy(
                Map.Entry::getKey, Collectors.mapping(Map.Entry::getValue, Collectors.toList())));

use result/print ..

myResultMap.forEach((k,v)-> {
    System.out.println(k + " : " + v);
});

// car : [bmw, suzuki, hyundai]
// bike : [honda, tvs]

1 Comment

@Eritean: No working for me. That list of throwing error.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.