【问题标题】:Sorting HashMap values in Java not giving back right order在Java中对HashMap值进行排序没有给出正确的顺序
【发布时间】:2013-03-27 13:48:03
【问题描述】:

我在将HashMapsJava 中的值排序时遇到了一些问题。 我的代码是:

 @SuppressWarnings("unchecked")
          Map<String, Integer> scores = ((HashMap<String, Integer>) prefs.get());
          Map<String, Integer> sortedscores = sortByValues(scores);
          printMap(scores);
          System.out.println("==============");
          printMap(sortedscores);

prefs.get() 返回一个 Map&lt;String, ?&gt; 我将其转换为 &lt;String, Integer &gt;

排序函数:

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 new LinkedHashMap<K,V>(sortedByValues);
}
public static void printMap(Map<String, Integer> unsortMap){
    for (Map.Entry entry : unsortMap.entrySet()) {
        System.out.println("Key : " + entry.getKey() 
                               + " Value : " + entry.getValue());
    }
}

输出是:

Key : John Doe Value : 1000
Key : balazs Value : 975
Key : Balazs Value : 900
Key : aladar Value : 975
Key : balazs2 Value : 975
Key : score Value : 1000
Key : house Value : 1037
==============
Key : balazs Value : 975
Key : aladar Value : 975
Key : balazs2 Value : 975
Key : Balazs Value : 900
Key : house Value : 1037
Key : John Doe Value : 1000
Key : score Value : 1000

第一个是未排序的,第二个是排序的。 我的问题是第二个输出不是 DESC 顺序(按值)

编辑: 如果我自己创建一个 hasmap 就可以了:

Map<String, Integer> unsortMap = new HashMap<String, Integer>();
        unsortMap.put("asd", 1);
        unsortMap.put("asd2r1", 5);
        unsortMap.put("house", 7);
        unsortMap.put("3", 124);
        unsortMap.put("7", 4);
        unsortMap.put("5", 6);
        unsortMap.put("6", 2);
        unsortMap.put("8", 0);

但如果我用这个试试:Map&lt;String, Integer&gt; scores = ((HashMap&lt;String, Integer&gt;) prefs.get()); 我会得到那个奇怪的命令。

【问题讨论】:

  • 好的,这里有什么问题?
  • 值应该是按DESC顺序排序的,但是975,975,975,900,1037,1000,1000 1037不是应该在的位置
  • 如果您的排序顺序混乱,比较器中似乎有问题。

标签: java sorting hashmap


【解决方案1】:

您的比较器看起来不符合specification

        int compare = map.get(k2).compareTo(map.get(k1));
        if (compare == 0) return 1;
        else return compare;

为什么两个条目相等时返回 1?

【讨论】:

  • 试过了,没有任何反应,输出是一样的
【解决方案2】:

你基本上应该重写这个:

public int compare(K k1, K k2) {
    int compare = map.get(k2).compareTo(map.get(k1));
    if (compare == 0) return 1;
    else return compare;
}

到:

public int compare(K k1, K k2) {
    return map.get(k2).compareTo(map.get(k1));
}

当两个值相等时,您实际上是在说一个大于另一个……这没有多大意义。如果键是可比较的,请使用自然比较。

【讨论】:

  • 我试过了,但是输出是一样的,只是缺少重复的条目
【解决方案3】:

我认为问题出在返回句中:

Map<K, V> sortedByValues = new TreeMap<K, V>(valueComparator);
sortedByValues.putAll(map);
return new LinkedHashMap<K,V>(sortedByValues);

您有一个已排序的地图,然后您将所有对放在一个新地图中,因此它们再次未排序。尝试这样做:

Map<K, V> sortedByValues = new TreeMap<K, V>(valueComparator);
sortedByValues.putAll(map);
return sortedByValues;

【讨论】:

    【解决方案4】:

    找到解决方案: 问题是它比较的是字符串而不是整数。我尝试的转换

    Map<String, Integer> scores = ((HashMap<String, Integer>) prefs.get());
    

    没有将其转换为整数。 所以我使用了一个正确的循环:

       for (@SuppressWarnings("rawtypes") Map.Entry entry : scores.entrySet()) {
           scoresInt.put(entry.getKey().toString(), Integer.parseInt(entry.getValue().toString()));
       }
    

    将 hasmap 转换为排序就像一个魅力。

    【讨论】:

      猜你喜欢
      • 2014-12-11
      • 2011-05-08
      • 1970-01-01
      • 2015-04-10
      • 1970-01-01
      • 2023-04-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多