如何使用自定义比较器对值而不是键对 java 映射进行排序

发布于 2025-01-10 17:19:45 字数 752 浏览 4 评论 0原文

我们如何通过比较映射的值而不是键的值来对映射的内容进行排序?例如,我们如何实现一种方法 sortByAbsoluteValue ,该方法将映射条目从绝对值最高的条目排序到绝对值最低的条目:

HashMap<String,Integer> hashmap=new HashMap<String,Integer>();
    hashmap.put("product5",100);
    hashmap.put("product6",-20);
    hashmap.put("product3",10);
    hashmap.put("product4",5);
    hashmap.put("product1",15);
    hashmap.put("product2",-40);
    hashmap.put("product9",0);
    hashmap.put("product7",70);
    hashmap.put("product8",30);
Map<String, Integer> map = sortByAbsoluteValue(hashmap);

其中 map.toString() 将输出

{product5=100, product7=70, product2=-40, product8=30, product6=-20, product1=15, product3=10, product4=5, product9=0}

How can we order the content of a map by comparing its values instead of the value of its keys? For example, how can we implement a method sortByAbsoluteValue that orders the map entries from the one with highest absolute value to lowest absolute value:

HashMap<String,Integer> hashmap=new HashMap<String,Integer>();
    hashmap.put("product5",100);
    hashmap.put("product6",-20);
    hashmap.put("product3",10);
    hashmap.put("product4",5);
    hashmap.put("product1",15);
    hashmap.put("product2",-40);
    hashmap.put("product9",0);
    hashmap.put("product7",70);
    hashmap.put("product8",30);
Map<String, Integer> map = sortByAbsoluteValue(hashmap);

Where map.toString() would output

{product5=100, product7=70, product2=-40, product8=30, product6=-20, product1=15, product3=10, product4=5, product9=0}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

酷遇一生 2025-01-17 17:19:45

虽然我同意一些暗示列表更适合查找排序结果的评论,但 Java 确实允许使用 Comparator<> 等某些映射(例如 TreeMap)进行排序> 功能。

不幸的是,Map 总是按键排序,但幸运的是,Java 还提供 LinkedHashMap 来维护它们的插入顺序。

因此,这里的技巧是首先使用 TreeMap 中的 Comparator 以值作为键进行排序,然后将排序结果插入到 LinkedHashMap >:

private LinkedHashMap<String, Integer> sortByAbsoluteValue(Map<String, Integer> unsorted)
{
    // assemble the comparator function
    Comparator<Integer> sortedByAbsValue = Comparator.comparingInt(Math::abs);
    Comparator<Integer> sortedByAbsValueReversed = sortedByAbsValue.reversed();

    // group by value, sorting using the custom comparator
    TreeMap<Integer, List<Map.Entry<String, Integer>>> sorted = new TreeMap<>(sortedByAbsValueReversed);
    sorted.putAll(unsorted.entrySet().stream().collect(Collectors.groupingBy(Map.Entry::getValue)));

    // assemble back into a map that maintains insertion order
    return sorted.entrySet()
            .stream()
            .flatMap(kv -> kv.getValue().stream())
            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> b, LinkedHashMap::new));
}

While I agree with some of the comments hinting that a list is better suited when looking for sorted results, Java does allow some maps like the TreeMap to be sorted using Comparator<> functions.

Unfortunately, Maps are always sorted by key, but luckily, Java also provides LinkedHashMap which maintain their insertion order.

So the trick here is to first sort using the Comparator in a TreeMap using the value as a key, and then insert the sorted result to a LinkedHashMap:

private LinkedHashMap<String, Integer> sortByAbsoluteValue(Map<String, Integer> unsorted)
{
    // assemble the comparator function
    Comparator<Integer> sortedByAbsValue = Comparator.comparingInt(Math::abs);
    Comparator<Integer> sortedByAbsValueReversed = sortedByAbsValue.reversed();

    // group by value, sorting using the custom comparator
    TreeMap<Integer, List<Map.Entry<String, Integer>>> sorted = new TreeMap<>(sortedByAbsValueReversed);
    sorted.putAll(unsorted.entrySet().stream().collect(Collectors.groupingBy(Map.Entry::getValue)));

    // assemble back into a map that maintains insertion order
    return sorted.entrySet()
            .stream()
            .flatMap(kv -> kv.getValue().stream())
            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> b, LinkedHashMap::new));
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文