【问题标题】:Sorting the Map<Key,Value> in descending order based on the value [duplicate]根据值按降序对 Map<Key,Value> 进行排序 [重复]
【发布时间】:2012-07-23 18:37:22
【问题描述】:

可能重复:
How to sort a Map<Key, Value> on the values in Java?

我正在使用映射接口从文件中读取数据,然后将其中的值存储为键值对。文件格式如下

 A 34
 B 25
 c 50

我将从该文件中读取数据并将其存储为键值对,然后将其显示给用户。我的要求是以这种格式显示结果

C 50
A 34
B 25

因此我需要按值的降序对地图进行排序。这样我就可以将这些显示为我的结果..我已经阅读了这个并找到了下面的代码

static <K,V extends Comparable<? super V>> SortedSet<Map.Entry<K,V>> entriesSortedByValues(Map<K,V> map) {
        SortedSet<Map.Entry<K,V>> sortedEntries = new TreeSet<Map.Entry<K,V>>(
            new Comparator<Map.Entry<K,V>>() {
                @Override public int compare(Map.Entry<K,V> e1, Map.Entry<K,V> e2) {
                    int res = e1.getValue().compareTo(e2.getValue());
                    return res != 0 ? res : 1; // Special fix to preserve items with equal values
                }
            }
        );
        sortedEntries.addAll(map.entrySet());
        return sortedEntries;
    }

我希望这是按升序对值进行排序,我只是想知道这种方法是否正确或其他一些有效的方法对我有帮助吗?

【问题讨论】:

  • 也许你应该看看 Guava。见this评论。
  • @NandaKumar:Sets 不允许重复,例如使用List。如果你开始允许他们,你就违反了Comparator 的合同!
  • `map.entrySet().stream().sorted(Comparator.comparing(e->-e.getValue())).forEach(System.out::println);`跨度>

标签: java map hashmap


【解决方案1】:

由于您可以有重复的值,因此您根本不应该使用 Set。更改为 List 并对其进行排序。你的 entriesSortedByValues 看起来像这样:

static <K,V extends Comparable<? super V>> 
            List<Entry<K, V>> entriesSortedByValues(Map<K,V> map) {

    List<Entry<K,V>> sortedEntries = new ArrayList<Entry<K,V>>(map.entrySet());

    Collections.sort(sortedEntries, 
            new Comparator<Entry<K,V>>() {
                @Override
                public int compare(Entry<K,V> e1, Entry<K,V> e2) {
                    return e2.getValue().compareTo(e1.getValue());
                }
            }
    );

    return sortedEntries;
}

注意:在您的示例输出中,值是递减的。如果您希望它们升序,请改用e1.getValue().compareTo(e2.getValue())


示例:

public static void main(String args[]) {

    Map<String, Integer> map = new HashMap<String, Integer>();
    map.put("A", 34);
    map.put("B", 25);
    map.put("C", 50);
    map.put("D", 50); // "duplicate" value

    System.out.println(entriesSortedByValues(map));
}

输出:

[D=50, C=50, A=34, B=25]

【讨论】:

  • 为我工作。谢谢!
  • 每个看到这个的人都应该使用sortedEntries.sort() 而不是Collections 这样:sortedEntries.sort((e1, e2) -&gt; e2.getValue().compareTo(e1.getValue()));
【解决方案2】:

编写您自己的comparator 并将其传递给TreeMap

class MyComparator implements Comparator {

Map map;

public MyComparator(Map map) {
    this.map = map;
}

public int compare(Object o1, Object o2) {

    return ((Integer) map.get(o2)).compareTo((Integer) map.get(o1));

}
}

在测试课中

Map<String, Integer> lMap=new HashMap<String, Integer>();
    lMap.put("A", 35);
    lMap.put("B", 25);
    lMap.put("C", 50);

    MyComparator comp=new MyComparator(lMap);

    Map<String,Integer> newMap = new TreeMap(comp);
    newMap.putAll(lMap);

输出:

C=50
A=35
B=25

【讨论】:

  • 如果您添加 lMap.put("D", 50),这将不起作用,因为它会被视为重复(实际上会用 50 覆盖任何其他值,例如 "C")。
  • 不允许重复值。
  • @amicngh:感谢您的友好解决方案。但是,我希望允许重复值。获得相同结果的可能方法是什么。谢谢。
  • 以下代码将起作用。 public Map sortByValue(Map map) { List list = new LinkedList(map.entrySet()); Collections.sort(list, new Comparator() { public int compare(Object o2, Object o1) { return ((Comparable) ((Map.Entry) (o1)).getValue()) .compareTo(((Map.Entry ) (o2)).getValue()); } });映射结果 = new LinkedHashMap(); for (Iterator it = list.iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry)it.next();结果.put(entry.getKey(), entry.getValue()); } 返回结果; }
  • 你应该使用 new TreeMap(Collections.reverseOrder());。 Map newMap = new TreeMap(Collections.reverseOrder()); newMap.putAll(myMap);
猜你喜欢
  • 2021-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-07
  • 2013-03-06
  • 1970-01-01
相关资源
最近更新 更多