在使用流展平/分组时如何在此HashMap上排序?

时间:2019-03-08 20:31:47

标签: java java-8 java-stream

昨天我问了一个问题,将HashMap展平/分组。我收到了很大的建议,建议我这样做。

return new ArrayList<>(map.entrySet().stream()
    .collect(Collectors.groupingBy(
        Map.Entry::getValue,
        Collectors.mapping(Map.Entry::getKey, Collectors.joining(","))))
    .values())

但是,我希望我的逗号分隔字符列表按字母顺序排序。这些注释建议我尝试使用TreeMap::new作为groupingBy()的参数,但是当我尝试使用此方法时,我的字符列表仍未排序:

return new ArrayList<>(map.entrySet().stream()
    .collect(Collectors.groupingBy(
        Map.Entry::getValue,
        TreeMap::new,
        Collectors.mapping(Map.Entry::getKey, Collectors.joining(","))))
    .values())

下面是我的原始问题,并带有该帖子的链接。

考虑到字母到数字的映射,我想返回一个字符串列表,其中每个字符串都是一个用逗号分隔的字母列表,这些字母按字母的关联数字分组。

对于此地图

    Map<String, Integer> map = new HashMap<String, Integer>();
    map.put("A", 1);
    map.put("B", 2);
    map.put("C", 4);
    map.put("D", 1);
    map.put("E", 1);
    map.put("F", 2);

我想返回一个包含以下内容的列表:

"A,D,E" "B,F", "C"

有什么建议可以使用1.8流功能实现吗?

How to flatten and group this HashMap, using streams?

3 个答案:

答案 0 :(得分:2)

在执行操作之前将地图转到TreeMap,然后按键将在输出中按顺序排列。

//                         * here
return new ArrayList<>(new TreeMap(map).entrySet().stream()
.collect(Collectors.groupingBy(
    Map.Entry::getValue,
    TreeMap::new,
    Collectors.mapping(Map.Entry::getKey, Collectors.joining(","))))
.values())

答案 1 :(得分:1)

这也可能对您有用:

return new ArrayList<>(map.entrySet().stream()
        .collect(Collectors.groupingBy(
                Map.Entry::getValue,
                TreeMap::new,
                Collectors.mapping(Map.Entry::getKey, Collectors.collectingAndThen(Collectors.toList(), l -> {
                    Collections.sort(l);
                    return String.join(",", l);
                }))))
        .values());

答案 2 :(得分:0)

调整链接问题的答案之一,这应该可以满足您的需求:

List<String> result = map.entrySet().stream()
        .collect(Collectors.groupingBy(Map.Entry::getValue))
        .values().stream()
        .map(e -> e.stream()
                .map(Map.Entry::getKey)
                .sorted() // <<< modified this
                .collect(Collectors.joining(",")))
        .collect(Collectors.toList());