【问题标题】:grouping array of Strings by their first value using java 8 Stream使用java 8 Stream按第一个值对字符串数组进行分组
【发布时间】:2018-05-26 04:34:38
【问题描述】:

我有一个包含两个字符串的数组列表:

List<String[]> pets = {["Alice", "dog"], ["Bob", "horse"], ["Alice", "cat"], ["Bob", "cat"]}

我想把它们变成一个从字符串到字符串列表的映射,如下所示:

Map<String, List<String>>> pets = Map where
"Alice" maps to the List {"dog, "cat"}
"Bob" maps to the List {"horse", "cat"}

即我们取数组的第一个元素,并将第一个元素彼此相等的所有元素组合在一起。解决这个问题的必要方法是遍历元素,并逐步构建一个 Map。有没有办法用 java Streams 来做到这一点,即使用 Collector 或 reduce?

【问题讨论】:

    标签: java-8 java-stream


    【解决方案1】:

    当然可以!

    您可以按每个数组的第一个元素进行分组,这将是映射键,然后应用映射收集器来获取相应的值。

     Map<String, List<String>> resultSet = pets.stream()
                    .collect(groupingBy(array -> array[0],
                            collectingAndThen(mapping(e -> Arrays.copyOfRange(e, 1, e.length),
                                    toList()),
                                    f -> f.stream().flatMap(Arrays::stream)
                                    .collect(toList()))));
    

    或:

     Map<String, List<String>> resultSet = pets.stream()
                    .collect(groupingBy(array -> array[0],
                    flatMapping(e -> Arrays.stream(Arrays.copyOfRange(e, 1, e.length)),
                                        toList())));
    

    注意,此解决方案使用 flatMapping 收集器,该收集器仅在 JDK-9 中可用。

    【讨论】:

    • 也可以在第二个示例中使用Arrays.stream(e).skip(1) 而不是Arrays.stream(Arrays.copyOfRange(e, 1, e.length))
    • 或者更好,Arrays.stream(e, 1, e.length)
    • 谢谢。之前没有看到 groupingBy 方法。
    猜你喜欢
    • 2022-05-22
    • 1970-01-01
    • 1970-01-01
    • 2015-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-30
    • 1970-01-01
    相关资源
    最近更新 更多