使用Java 8 Streams创建和反转MultiMap

时间:2017-04-06 04:07:18

标签: java-8 java-stream multimap flatmap

如何使用Java 8流或Multimaps将Set<Result>转换为Map<Item, Set<String>>SetMultimap<Item, String>,其中Result为:

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

例如,我从:

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

并以:

结束
item1:
    - name1
item2:
    - name1
    - name2
item3:
    - name2

2 个答案:

答案 0 :(得分:3)

以下代码段中的两个重要方法是Stream.flatMap&amp; 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())));

答案 1 :(得分:2)

一旦jdk-9中有Collectors.flatMapping,它可能看起来有点不同。此外,您的Item个实例需要在某种程度上具有可比性,或者您可以在groupBy中指定(例如,通过字段'itemName'):

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()))));