Create a map from the map list

I have a list of cards.

List<Map<Integer, String>> 

Values ​​in the list, for example,

 <1, String1> <2, String2> <1, String3> <2, String4> 

As a final result, I need a map>, for example

 <1, <String1, String3>> <2, <String2, String4>> 

How can I achieve this in Java.

THE CODE:

 List<Map<Integer, String>> genericList = new ArrayList<Map<Integer,String>>(); for(TrackActivity activity : activityMajor){ Map<Integer, String> mapIdResponse = activity.getMapIdResponse(); genericList.add(mapIdResponse); } 

Now this genericList is the entry to and from this list, based on the same identifiers in which I want

 Map<Integer, List<String>> mapIdResponseList 

Basically, to combine responses that are String based on identifiers, group the responses with the same identifier in the list, and then create a new map with this identifier as the key and list as the value.

+7
java hashmap
source share
2 answers

You can do this with Java 8:

 private void init() { List<Map<Integer, String>> mapList = new ArrayList<>(); Map<Integer, String> map1 = new HashMap<>(); map1.put(1, "String1"); mapList.add(map1); Map<Integer, String> map2 = new HashMap<>(); map2.put(2, "String2"); mapList.add(map2); Map<Integer, String> map3 = new HashMap<>(); map3.put(1, "String3"); mapList.add(map3); Map<Integer, String> map4 = new HashMap<>(); map4.put(2, "String4"); mapList.add(map4); Map<Integer, List<String>> response = mapList.stream() .flatMap(map -> map.entrySet().stream()) .collect( Collectors.groupingBy( Map.Entry::getKey, Collectors.mapping( Map.Entry::getValue, Collectors.toList() ) ) ); response.forEach((i, l) -> { System.out.println("Integer: " + i + " / List: " + l); }); } 

This will print:

Integer: 1 / List: [String1, String3]
Integer: 2 / List: [String2, String4]

The explanation (pretty much justified), I'm afraid I can't explain every detail, you need to first understand the basics of the Stream API and Collectors introduced in Java 8:

  • Get Stream<Map<Integer, String>> from mapList .
  • Use the flatMap operator, which roughly maps the stream to an existing stream.
    Here: I convert all Map<Integer, String> to Stream<Map.Entry<Integer, String>> and add them to an existing stream, so now it is also of type Stream<Map.Entry<Integer, String>> .
  • I am going to compile Stream<Map.Entry<Integer, String>> into Map<Integer, List<String>> .
  • To do this, I use Collectors.groupingBy , which creates Map<K, List<V>> based on the grouping function a Function , which maps Map.Entry<Integer, String> to Integer in this case.
  • To do this, I use a method link that exactly does what I want, namely Map.Entry::getKey , it works with Map.Entry and returns Integer .
  • At this point, I would have Map<Integer, List<Map.Entry<Integer, String>>> , if I hadn't done the extra processing.
  • To get the correct signature, I have to add the downstream to Collectors.groupingBy , which the collector must provide.
  • For this downstream, I use a collector that maps my Map.Entry entries to their String values ​​via the Map.Entry::getValue .
  • I also need to indicate how they are assembled, namely Collectors.toList() here, since I want to add them to the list.
  • And this is how we get Map<Integer, List,String>> .
+12
source share

Take a look at the guava MultiMap. It should be exactly what you are looking for:

http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#Multimap

0
source share

All Articles