Java Map 按值排序

标签 java sorting hashmap comparator treemap

我正在寻找排序的方法 Map<String, Integer>按值(value)观。我找到了 this post ,它解决了我的排序问题,但不完全是。根据帖子,我写了以下代码:

import java.util.*;

public class Sort {

    static class ValueComparator implements Comparator<String> {

        Map<String, Integer> base;

        ValueComparator(Map<String, Integer> base) {
            this.base = base;
        }

        @Override
        public int compare(String a, String b) {
            if (base.get(a) >= base.get(b)) {
                return 1;
            } else {
                return -1;
            }
        }
    }

    public static void main(String[] args) {
        HashMap<String, Integer> map = new HashMap<String, Integer>();
        ValueComparator vc = new ValueComparator(map);
        TreeMap<String, Integer> sorted = new TreeMap<String, Integer>(vc);
        map.put("A", 1);
        map.put("B", 2);
        sorted.putAll(map);
        for (String key : sorted.keySet()) {
            System.out.println(key + " : " + sorted.get(key)); // why null values here?
        }
        System.out.println(sorted.values()); // But we do have non-null values here!
    }
}

输出:

A : null
B : null
[1, 2]
BUILD SUCCESSFUL (total time: 0 seconds)

从输出中可以看出,get方法总是返回 null .原因是我的ValueComparator.compare()方法从不返回 0 ,这是我通过制作 this post 得出的.

有人在那篇文章中提出以下建议来解决 null值(value)问题:

        public int compare(String a, String b) {
            if (base.get(a) > base.get(b)) {
                return 1;
            }else if(base.get(a) ==  base.get(b)){
                return 0;
            }
            return -1;  
        }

我已经测试了这段代码,它引入了一个关键的合并问题。换句话说,当值相等时,它们对应的键被合并。

我还尝试了以下方法:

            public int compare(String a, String b) {
                if (a.equals(b)) return 0;
                if (base.get(a) >= base.get(b)) {
                    return 1;
                } else return -1;
            }

也不行。一些值仍然是 null .此外,此解决方法可能存在逻辑问题。

任何人都可以针对我的问题提出一个完全可行的解决方案吗?我希望按值排序功能起作用,并且 get同时工作的方法。

最佳答案

在您的比较函数中,当值相等时,您应该比较键。这将确保具有相同值的不同键不会被“合并”,因为它消除了本来比较相等的条目的歧义。

例如:

    @Override
    public int compare(String a, String b) {
        Integer x = base.get(a);
        Integer y = base.get(b);
        if (x.equals(y)) {
            return a.compareTo(b);
        }
        return x.compareTo(y);
    }

(您需要修改上面的代码以匹配您的空值策略)

请注意,您对值进行排序的方法非常脆弱。您的“已排序” map 将不支持添加新条目,这可能会造成混淆。

关于Java Map 按值排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13852725/

相关文章:

c++ - 如何将字符串的多重映射排序为值

java - 如何在应用 RowFilter 过滤后禁用 jtable 中的列标题排序

java - SonarQube 暗示 var 为 null 或可以为 null

java - 就性能而言哪个更好?

java - Dijkstra、广度优先还是塔防 A*?

在 Luke 中对 Lucene 文档进行排序

java - 如何获取 HashMap 值的属性?

java - 如何从另一个类调用HashMap的方法?

java - 无法在 linux 上使用 rsync 同步单个文件

java - 如何使模型更改在 JDatePicker 上可见?