Java Stream Collectors.toMap value is a Set

前端 未结 4 1162
旧巷少年郎
旧巷少年郎 2021-02-07 21:29

I want to use a Java Stream to run over a List of POJOs, such as the list List below, and transform it into a Map Map>

相关标签:
4条回答
  • 2021-02-07 22:02

    groupingBy does exactly what you want:

    import static java.util.stream.Collectors.*;
    ...
    as.stream().collect(groupingBy((x) -> x.name, mapping((x) -> x.property, toSet())));
    
    0 讨论(0)
  • 2021-02-07 22:09

    Also, you can use the merger function option of the Collectors.toMap function Collectors.toMap(keyMapper,valueMapper,mergeFunction) as follows:

    final Map<String, String> m = as.stream()
                                    .collect(Collectors.toMap(
                                              x -> x.name, 
                                              x -> x.property,
                                              (property1, property2) -> property1+";"+property2);
    
    0 讨论(0)
  • 2021-02-07 22:13

    @Nevay 's answer is definitely the right way to go by using groupingBy, but it is also achievable by toMap by adding a mergeFunction as the third parameter:

    as.stream().collect(Collectors.toMap(x -> x.name, 
        x -> new HashSet<>(Arrays.asList(x.property)), 
        (x,y)->{x.addAll(y);return x;} ));
    

    This code maps the array to a Map with a key as x.name and a value as HashSet with one value as x.property. When there is duplicate key/value, the third parameter merger function is then called to merge the two HashSet.

    PS. If you use Apache Common library, you can also use their SetUtils::union as the merger

    0 讨论(0)
  • 2021-02-07 22:28

    Same Same But Different

    Map<String, Set<String>> m = new HashMap<>();
    
    as.forEach(a -> {
        m.computeIfAbsent(a.name, v -> new HashSet<>())
                .add(a.property);
        });
    
    0 讨论(0)
提交回复
热议问题