按键按升序对Map进行排序

4

我将尝试根据键值对对Map进行升序排序。给定以下Map

Map<Integer, String> map = new LinkedHashMap<Integer, String>();

map.put(5, "five");
map.put(1, "one");
map.put(3, "three");
map.put(0, "zero");

我想要这个订单:

0, zero
1, one
3, three
5, five

我写了下面的代码来实现这个功能:
    public <K, V extends Comparable<? super V>> Map<K, V> sortByKeyInAscendingOrder(Map<K, V> map)
{
    List<Entry<K, V>> list = new ArrayList<>(map.entrySet());
    list.sort(Entry.comparingByKey());

    Map<K, V> result = new LinkedHashMap<>();
    for (Entry<K, V> entry : list) {
        result.put(entry.getKey(), entry.getValue());
    }
    return result;
}

然而,当我调用sort()时,出现以下错误:
The method sort(Comparator<? super Map.Entry<K,V>>) in the type List<Map.Entry<K,V>> is not applicable for the arguments (Comparator<Map.Entry<Comparable<? super Comparable<? super K>>,Object>>)

我曾写过相似代码(功能正常),用于按值排序(将 Entry.comparingByKey() 改为 Entry.comparingByValue()),但是不知道为什么当我尝试按键排序时会出现上述错误。

我该如何解决这个问题?

谢谢。

4个回答

3
您需要使K可比较以进行排序;而对V的限制是错误的(但无关紧要)。"最初的回答"
public <K extends Comparable<? super K>, V> Map<K, V> sortByKeyInAscendingOrder(Map<K, V> map)

请注意,更简单的方法可能是:

最初的回答
return new LinkedHashMap<>(new TreeMap<>(map));

或者

return map.entrySet().stream()
    .sorted(Entry.comparingKey())
    .collect(toMap(k -> k, v -> v, LinkedHashMap::new));

哇,这么多好答案!你是第一个回复的,所以我接受这个是正确答案。谢谢大家! - Alan Cook

3
你可以尝试使用Java 8流。最初的回答。
Map<Integer, String> map = new LinkedHashMap<Integer, String>();

    map.put(5, "five");
    map.put(1, "one");
    map.put(3, "three");
    map.put(0, "zero");

    map = map.entrySet().stream().sorted(Comparator.comparing(Map.Entry::getKey))
            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

    System.out.println(map);  //{0=zero, 1=one, 3=three, 5=five}

你可以在Map上使用forEach,来代替Original Answer。
map.forEach((k,v)->System.out.println(k+"  "+v));

2
"最初的回答"翻译成英文是 "Original Answer"。
以下是需要翻译的内容:

方法comparingByKey要求其键,即K类型参数,必须是Comparable,而不是(必须)它的值,V

将边界? extends Comparable<? super K>V移动到K。更改为:

<K, V extends Comparable<? super K>>

to

<K extends Comparable<? super K>, V>

当然,将V设为Comparable是可选的,但请将该限制条件应用于自身,而不是应用于K


V extends Comparable<? super V>

2
使用TreeMap如何?它可以按自然顺序保持键排序:https://docs.oracle.com/javase/7/docs/api/java/util/TreeMap.html。如果需要从现有映射创建它,请使用其参数化构造函数:
TreeMap<Integer,String> treeMap = new TreeMap<>(map);

使用HashMap不能保证顺序,而LinkedHashMap保持插入顺序。如果要按键排序,请使用TreeMap。

最初的回答

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