繁体   English   中英

如何获取列表,将其收集到 map,然后使用 Java Streams 进行排序?

[英]How do I take a list, collect it to a map, then sort using Java Streams?

我有以下代码....

public Map<Object, Integer> getRankings(){
    Stream<String> stream = votes.stream();
    return stream
            .collect(Collectors.toMap(s -> s, s -> 1, Integer::sum));
}

这很好用,但现在我想根据计数对 map 进行排序。 我在收集后尝试了排序,但该方法不可用,因为 stream 现在是 map。 在返回之前我将如何对其进行排序? 我可以使用 Stream 还是必须排序为 map?

地图基本上是未排序的。 因此,您不能暗示订单。

然而,map 的一些特定子类确实包含了排序的定义。 重点是, java.util.Map本身没有,所以我们必须深入研究子类; 例如,不能订购new java.util.HashMap ,期间。

LinkedHashMap 按“插入顺序”排序,因此,您可以为其强制执行顺序。

SortedMap 类(例如 TreeMap)是按key排序的,带有一个比较器,因此也不可能按 value 对它们进行排序。

一般的答案是你遇到了一些问题 X 并想:我知道。 我将通过按值排序的 map 来解决这个未知问题 X,但这不太可能是解决 X 的好方法,不幸的是,你没有说 X 是什么:你只是在问关于如何得到一个 map 按 java 中的值排序,因此我们现在卡住了。 Oooooof,这真的很难做到。

以防万一你仍然认为你的这个“按值排序的地图”的想法是如何解决 X:

没有.toLinkedHashMap 有一个带有第四个参数的Collectors.toMap变体,它是 lambda,它为您生成 map。 使用那个,传入一个 lambda 来生成一个new LinkedHashMap 然后你需要强制 stream API 以正确的顺序插入,这是不可能的。

所以,我们需要使这成为可能:首先收集到一个普通的简 map。 然后通过询问 map 的入口集并在其上流式传输,将其重新旋转为 ZF7B44CFFAFD5C52223D5498196C8A2E7BZ。 然后,将 stream 转换为排序后的 stream,在entry.getValue()上排序。 然后使用允许您提供 mapSupplier 的 Collectors.toMap 方法之一,将生成的顺序排序 stream 收集回 map。 您不需要在此处分组 toMap - 您的 stream 对象已准备好逐字插入。

这当然是低效的,并且有一个中间阶段 map 然后立即被扔进垃圾箱。 但这是做到这一点的唯一方法,这可以追溯到:按值排序的地图相当棘手。

该解决方案有效,但我会以更“流畅”的方式进行检查。

public Map<Object, Integer> getRankings(){
    Stream<String> stream = votes.stream();
    Map<Object, Integer> map = stream
            .collect(Collectors.toMap(s -> s, s -> 1, Integer::sum));
    return Vote.sortByValues(map);
}

public static <K, V extends Comparable<V>> Map<K, V> sortByValues(final Map<K, V> map) {
    Comparator<K> valueComparator =  new Comparator<K>() {
        public int compare(K k1, K k2) {
            int compare = map.get(k2).compareTo(map.get(k1));
            if (compare == 0) return 1;
            else return compare;
        }
    };
    Map<K, V> sortedByValues = new TreeMap<K, V>(valueComparator);
    sortedByValues.putAll(map);
    return sortedByValues;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM