如何在 Java 中按键对 Map 值进行排序?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/922528/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 21:07:32  来源:igfitidea点击:

How to sort Map values by key in Java?

javadictionaryhashmap

提问by n00bstackie

I have a Map that has strings for both keys and values.

我有一个包含键和值字符串的 Map。

Data is like following:

数据如下:

"question1", "1"
"question9", "1"
"question2", "4"
"question5", "2"

“问题 1”、“1”、
“问题 9”、“1”、
“问题 2”、“4”、
“问题 5”、“2”

I want to sort the map based on its keys. So, in the end, I will have question1, question2, question3....and so on.

我想根据其键对地图进行排序。所以,最后,我会question1, question2, question3……等等。


Eventually, I am trying to get two strings out of this Map.


最终,我试图从这个 Map 中获取两个字符串。

  • First String: Questions ( in order 1 ..10)
  • Second String: Answers (in the same order as the question)
  • 第一个字符串:问题(按顺序 1 ..10)
  • 第二个字符串:答案(与问题的顺序相同)

Right now I have the following:

现在我有以下几点:

Iterator it = paramMap.entrySet().iterator();
while (it.hasNext()) {
    Map.Entry pairs = (Map.Entry) it.next();
    questionAnswers += pairs.getKey() + ",";
}

This gets me the questions in a string but they are not in order.

这让我把问题放在一个字符串中,但它们不是按顺序排列的。

回答by Jherico

Short answer

简答

Use a TreeMap. This is precisely what it's for.

使用一个TreeMap. 这正是它的用途。

If this map is passed to you and you cannot determine the type, then you can do the following:

如果此映射传递给您并且您无法确定类型,那么您可以执行以下操作:

SortedSet<String> keys = new TreeSet<>(map.keySet());
for (String key : keys) { 
   String value = map.get(key);
   // do something
}

This will iterate across the map in natural order of the keys.

这将按键的自然顺序遍历地图。



Longer answer

更长的答案

Technically, you can use anything that implements SortedMap, but except for rare cases this amounts to TreeMap, just as using a Mapimplementation typically amounts to HashMap.

从技术上讲,您可以使用任何实现 的东西SortedMap,但除了极少数情况外,这相当于TreeMap,就像使用Map实现通常相当于 一样HashMap

For cases where your keys are a complex type that doesn't implement Comparable or you don't want to use the natural order then TreeMapand TreeSethave additional constructors that let you pass in a Comparator:

因为你的键是一个复杂类型案件没有实现Comparable,或者你不想使用自然顺序,然后TreeMapTreeSet有额外的构造函数,让你在传递Comparator

// placed inline for the demonstration, but doesn't have to be a lambda expression
Comparator<Foo> comparator = (Foo o1, Foo o2) -> {
        ...
    }

SortedSet<Foo> keys = new TreeSet<>(comparator);
keys.addAll(map.keySet());

Remember when using a TreeMapor TreeSetthat it will have different performance characteristics than HashMapor HashSet. Roughly speaking operations that find or insert an element will go from O(1)to O(Log(N)).

请记住,在使用TreeMapor 时TreeSet,它将具有与HashMapor不同的性能特征HashSet。粗略地说,查找或插入元素的操作将从O(1)O(Log(N))

In a HashMap, moving from 1000 items to 10,000 doesn't really affect your time to lookup an element, but for a TreeMapthe lookup time will be about 3 times slower (assuming Log2). Moving from 1000 to 100,000 will be about 6 times slower for every element lookup.

在 a 中HashMap,从 1000 项移动到 10,000 项并不会真正影响您查找元素的时间,但对于 a TreeMap,查找时间将慢约 3 倍(假设为 Log 2)。对于每个元素查找,从 1000 移动到 100,000 将慢 6 倍。

回答by AgileJon

Use a TreeMap!

使用树图

回答by TrayMan

Assuming TreeMap is not good for you (and assuming you can't use generics):

假设 TreeMap 对您不利(并假设您不能使用泛型):

List sortedKeys=new ArrayList(yourMap.keySet());
Collections.sort(sortedKeys);
// Do what you need with sortedKeys.

回答by Manoj Singh

List<String> list = new ArrayList<String>();
Map<String, String> map = new HashMap<String, String>();
for (String str : map.keySet()) {
 list.add(str);
}
Collections.sort(list);
for (String str : list) {
 System.out.println(str);
}

回答by Manoj Singh

We can also sort the key by using Arrays.sort method.

我们还可以使用 Arrays.sort 方法对键进行排序。

Map<String, String> map = new HashMap<String, String>();
Object[] objArr = new Object[map.size()];
for (int i = 0; i < map.size(); i++) {
objArr[i] = map.get(i);
}
Arrays.sort(objArr);
for (Object str : objArr) {
System.out.println(str);
}

回答by Manoj Singh

Using the TreeMapyou can sort the map.

使用TreeMap可以对地图进行排序。

Map<String, String> map = new HashMap<>();        
Map<String, String> treeMap = new TreeMap<>(map);
for (String str : treeMap.keySet()) {
    System.out.println(str);
}

回答by M-D

If you already have a map and would like to sort it on keys, simply use :

如果您已经有一张地图并想按键对其进行排序,只需使用:

Map<String, String> treeMap = new TreeMap<String, String>(yourMap);

A complete working example :

一个完整的工作示例:

import java.util.HashMap;
import java.util.Set;
import java.util.Map;
import java.util.TreeMap;
import java.util.Iterator;

class SortOnKey {

public static void main(String[] args) {
   HashMap<String,String> hm = new HashMap<String,String>();
   hm.put("3","three");
   hm.put("1","one");
   hm.put("4","four");
   hm.put("2","two");
   printMap(hm);
   Map<String, String> treeMap = new TreeMap<String, String>(hm);
   printMap(treeMap);
}//main

public static void printMap(Map<String,String> map) {
    Set s = map.entrySet();
    Iterator it = s.iterator();
    while ( it.hasNext() ) {
       Map.Entry entry = (Map.Entry) it.next();
       String key = (String) entry.getKey();
       String value = (String) entry.getValue();
       System.out.println(key + " => " + value);
    }//while
    System.out.println("========================");
}//printMap

}//class

回答by Aliti

Just use TreeMap

只需使用 TreeMap

new TreeMap<String, String>(unsortMap);

Be aware that the TreeMap is sorted according to the natural ordering of its 'keys'

请注意,TreeMap 是根据其“键”的自然顺序进行排序的

回答by M. Mashaye

This code can sort a key-value map in both orders i.e. ascending and descending.

此代码可以按升序和降序两种顺序对键值映射进行排序。

<K, V extends Comparable<V>> Map<K, V> sortByValues
     (final Map<K, V> map, int ascending)
{
     Comparator<K> valueComparator =  new Comparator<K>() {         
        private int ascending;
        public int compare(K k1, K k2) {
            int compare = map.get(k2).compareTo(map.get(k1));
            if (compare == 0) return 1;
            else return ascending*compare;
        }
        public Comparator<K> setParam(int ascending)
        {
            this.ascending = ascending;
            return this;
        }
    }.setParam(ascending);

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

As an example:

举个例子:

Map<Integer,Double> recommWarrVals = new HashMap<Integer,Double>();
recommWarrVals = sortByValues(recommWarrVals, 1);  // Ascending order
recommWarrVals = sortByValues(recommWarrVals,-1);  // Descending order

回答by akhil_mittal

Provided you cannot use TreeMap, in Java 8we can make use of toMap()method in Collectorswhich takes following parameters:

如果您不能使用TreeMap,在Java 8 中我们可以使用toMap()方法,Collectors该方法采用以下参数:

  • keymapper: mapping function to produce keys
  • valuemapper: mapping function to produce values
  • mergeFunction: a merge function, used to resolve collisions between values associated with the same key
  • mapSupplier: a function which returns a new, empty Map into which the results will be inserted.
  • keymapper: 生成键的映射函数
  • valuemapper: 生成值的映射函数
  • mergeFunction: 一个合并函数,用于解决与同一键关联的值之间的冲突
  • mapSupplier:一个函数,它返回一个新的空 Map,结果将被插入到其中。

Java 8 Example

Java 8 示例

Map<String,String> sample = new HashMap<>();  // push some values to map  
Map<String, String> newMapSortedByKey = sample.entrySet().stream()
                    .sorted(Map.Entry.<String,String>comparingByKey().reversed())
                    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
Map<String, String> newMapSortedByValue = sample.entrySet().stream()
                        .sorted(Map.Entry.<String,String>comparingByValue().reversed())
                        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1,e2) -> e1, LinkedHashMap::new));

We can modify the example to use custom comparator and to sort based on keys as:

我们可以修改示例以使用自定义比较器并根据键进行排序,如下所示:

Map<String, String> newMapSortedByKey = sample.entrySet().stream()
                .sorted((e1,e2) -> e1.getKey().compareTo(e2.getKey()))
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1,e2) -> e1, LinkedHashMap::new));