如何在 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
How to sort Map values by key in Java?
提问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 Map
implementation 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 TreeMap
and TreeSet
have additional constructors that let you pass in a Comparator
:
因为你的键是一个复杂类型案件没有实现Comparable,或者你不想使用自然顺序,然后TreeMap
和TreeSet
有额外的构造函数,让你在传递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 TreeMap
or TreeSet
that it will have different performance characteristics than HashMap
or HashSet
. Roughly speaking operations that find or insert an element will go from O(1)to O(Log(N)).
请记住,在使用TreeMap
or 时TreeSet
,它将具有与HashMap
or不同的性能特征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 TreeMap
the 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 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 TreeMap
you 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 Collectors
which 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));