如何对TreeMap<String, Integer>进行排序?

6
我有一个地图:TreeMap<String, Integer> m = new TreeMap<>();,其中包含整个字母表和值,显示每个字母在我的文本中出现的次数。我想按降序对该地图进行排序;也就是说,出现最频繁的字母位于第一行,输出的最后一行表示出现最少的字母。如果两个字母具有相同的频率,则字母表中先出现的字母必须先出现。如何实现呢?
我尝试使用比较器:
public int compare(String a, String b) {
        if (base.get(a) >= base.get(b) && a.compareToIgnoreCase(b) < 0) {
            return -1;
        } else {
            return 1;
        }
    }

但是输出结果并不完全正确,它输出的是:
D 3
E 3
A 2
S 5

大家好...之前发现这个,但并没有起到帮助作用。良好的输出应该是:

S 5
D 3
E 3
A 2

精确重复:https://dev59.com/1XA75IYBdhLWcg3w182G - JohnJohnGa
另一个重复的问题https://dev59.com/7HM_5IYBdhLWcg3wRw51 - mellamokb
@JohnJohnGa:不是的。我的问题有点不同。请看我的编辑。 - Katie
2个回答

3
您的比较器看起来不对 - 这个应该更好用:
```java 您的比较器看起来不对 - 这个应该更好用:``` ```java```
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 1;
    } else {
        int stringCompare = a.compareToIgnoreCase(b);
        return stringCompare == 0 ? 1 : stringCompare; // returning 0 would merge keys
    }
}

@Katie 抱歉,它是按升序排列的 - 已更正。 - assylias

3

由于自然排序与您的排序需求没有任何共同点:

List<Map.Entry<String, Integer>> entries = new ArrayList<>(m.entrieSet());

Collections.sort(entries, new Comparator<Map.Entry<String, Integer>>() {
    @Override
    public int compare(Map.Entry<String, Integer >a, Map.Entry<String, Integer>b) {
        if (a.getValue() < b.getValue()) { // Descending values
            return 1;
        } else if (a.getValue() > b.getValue()) {
            return -1;
        }
        return -a.getKey().compareTo(b.getKey()); // Descending keys
    }    
});

+1. 尝试像 OP 一样按值编写比较器是一个极其糟糕的想法,会导致代码混乱、出乎意料和难以调试。 - Louis Wasserman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接