【问题标题】:Number list from a Map地图中的号码列表
【发布时间】:2016-04-21 18:37:50
【问题描述】:

我有一个我正在简化的地图,但本质上包含一些数据的关键值,例如:

Yahya, 4 
John, 4
Blake, 2
Jill 2
Janoe, 6
Jilly 12
Zapon, 5
Zoe, 4
Hamed, 1

我需要订购这个才能得到以下输出:

1. Jilly, 12 pts
2. Janoe, 6 pts
3. Zapon, 5 pts
4. John, 4 pts
4. Yahya, 4 pts
4. Zoe, 4 pts
7. Blake, 2 pts
7. Jill, 2 pts
9. Hamed, 1 pts

我已经使用比较器根据值对 Map 值进行排序:

public <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;
}

并阅读:How to get element position from Java MapOrder HashMap alphabetically by value 等等,但不知道如何将它们组合在一起。

我知道你可以使用它来获取键值:

for (Map.Entry<String, Integer> entry : map.entrySet()){
    System.out.println(entry.getKey() + " ," + entry.getValue() + " pts"); 
}

但是缺少两个功能:

  1. 当键相同时按字母顺序排序
  2. 值相同时保持相同编号,之后跳转到正确计数。

试过这个:

Map<String, Integer> map = sortByValues(groupList);
            int count = 1;
            int counter = 1;
            int previousScore = 0;

            for (Map.Entry<String, Integer> entry : map.entrySet()) {

               //counter = count;
                if (previousScore == entry.getValue()) {

                    System.out.println(counter - 1 + " " + entry.getKey() + "," + entry.getValue() + " pts");

                } else {

                    System.out.println(counter + " " + entry.getKey() + "," + entry.getValue() + " pts");
                    previousScore = entry.getValue();
                    count++;
                }
                counter++;

            }

任何想法都受到赞赏和欢迎。任何人都可以提出一种方法来达到所需的结果吗?

【问题讨论】:

    标签: java sorting maps


    【解决方案1】:
    1. 在您的 ValueComparator 中,将 if (compare == 0) return 1; 替换为 if(compare == 0) return k1.compareTo(k2)
    2. 在生成“编号”时(您没有显示任何代码),保留两个计数。在每次迭代中增加其中一个,并将其分配给另一个,但前提是当前值与上一个不同。使用后者生成“编号”。

    【讨论】:

    • 感谢您的回答,但是...k1.compareTo(k2) 删除了重复值而不是编号,并且之前尝试了各种计数,因此提出了这个问题,因为我无法正确回答。有同样的想法,但不知道如何实现。
    • 也将K 声明为Comparable,与V 相同。或者,更好的是,摆脱泛型,只使用Map&lt;String, Integer&gt;,因为那是你真正需要的。如果您希望我们帮助您找出问题所在,请出示您的计数代码。
    【解决方案2】:

    这就是我最终使正确计数器起作用的结果:

    Map <String, Integer>map = sortByValues(leagueTable);
    
                int counter = 1;
                int previousScore = 0;
                int relativeCount = 0;
                int n= 0;
                for (Map.Entry<String, Integer> entry : map.entrySet())
                {
    
                   int value = entry.getValue();
    
    
                   if(previousScore == entry.getValue()){
    
                       if(n == 0){
    
                          relativeCount = counter-1;  
    
                       n++;
                       }
                   System.out.println(relativeCount + " " + entry.getKey() + "," + entry.getValue() + " pts");
    
                   }
                   else{
                   n=0;
                   System.out.println(counter + " " + entry.getKey() + "," + entry.getValue() + " pts");
                    previousScore = entry.getValue();
    
                   } 
                   counter++;
    
                }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-08-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-17
      相关资源
      最近更新 更多