How to create a reverse map when original map contains collection as the value?

  • A+

Let's say my original Map contains the following:

Map<String, Set<String>> original = Maps.newHashMap(); original.put("Scott", Sets.newHashSet("Apple", "Pear", "Banana"); original.put("Jack", Sets.newHashSet("Banana", "Apple", "Orange"); 

And I want to create a reversed Map containing the following:

  "Apple":  ["Scott", "Jack"]   "Pear":   ["Scott"]   "Banana": ["Scott", "Jack"]   "Orange": ["Jack"] 

I know it can be done in old fashion (pre-Java 8), but how do I achieve the same using Java Stream API?

Map<String, Set<String>> reversed = original.entrySet().stream().map(x -> ????).collect(??) 

There's similar question posted here, but that only works for single valued Maps.


You can break the Map into key-value pairs (where each key and value is a single String) by using flatMap, and then collect them as you wish:

Map<String,Set<String>> rev =     original.entrySet ()             .stream ()             .flatMap (e -> e.getValue ()                             .stream ()                             .map (v -> new SimpleEntry<String,String>(v,e.getKey ())))             .collect(Collectors.groupingBy (Map.Entry::getKey,                                             Collectors.mapping (Map.Entry::getValue,                                                                  Collectors.toSet()))); System.out.println (rev); 


{Apple=[Jack, Scott], Pear=[Scott], Orange=[Jack], Banana=[Jack, Scott]} 


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: