Creating and Inverting MultiMap with Java 8 Streams

How to convert Set<Result> to Map<Item, Set<String>> or SetMultimap<Item, String> using Java 8 or Multimaps streams, where Result :

 class Result { String name; Set<Item> items; } 

For example, I start with:

 result1: name: name1 items: - item1 - item2 result2: name: name2 items: - item2 - item3 

and end with:

 item1: - name1 item2: - name1 - name2 item3: - name2 
+5
source share
2 answers

two important methods in the code snippet below Stream.flatMap and Collectors.mapping :

 import java.util.Map.Entry; import java.util.AbstractMap.SimpleEntry; import static java.util.stream.Collectors.*; results.stream() //map Stream<Result> to Stream<Entry<Item>,String> .flatMap(it -> it.items.stream().map(item -> new SimpleEntry<>(item, it.name))) //group Result.name by Item .collect(groupingBy(Entry::getKey, mapping(Entry::getValue, toSet()))); 
+3
source

When there is Collectors.flatMapping in jdk-9, it may look a little different. Also, your Item instances must be comparable in some way, or you can specify this in groupBy (say, by the "itemName" field):

 Map<Item, Set<String>> map = results.stream() .collect(Collectors.flatMapping( (Result result) -> result.getItems() .stream() .map((Item item) -> new AbstractMap.SimpleEntry<>(item, result.getName())), Collectors.groupingBy(Entry::getKey, () -> new TreeMap<>(Comparator.comparing(Item::getItemName)), Collectors.mapping(Entry::getValue, Collectors.toSet())))); 
+2
source

Source: https://habr.com/ru/post/1266398/


All Articles