我对Java比较陌生,经常发现需要对值进行Map<Key,Value>排序。
由于这些值不是唯一的,我发现自己将keySet转换为一个数组,并使用自定义比较器通过数组排序对该数组进行排序,该比较器根据与该键关联的值进行排序。
有没有更简单的方法?
我对Java比较陌生,经常发现需要对值进行Map<Key,Value>排序。
由于这些值不是唯一的,我发现自己将keySet转换为一个数组,并使用自定义比较器通过数组排序对该数组进行排序,该比较器根据与该键关联的值进行排序。
有没有更简单的方法?
当前回答
如果您有重复的密钥,并且只有一小部分数据(<1000),并且您的代码不是性能关键型的,则可以执行以下操作:
Map<String,Integer> tempMap=new HashMap<String,Integer>(inputUnsortedMap);
LinkedHashMap<String,Integer> sortedOutputMap=new LinkedHashMap<String,Integer>();
for(int i=0;i<inputUnsortedMap.size();i++){
Map.Entry<String,Integer> maxEntry=null;
Integer maxValue=-1;
for(Map.Entry<String,Integer> entry:tempMap.entrySet()){
if(entry.getValue()>maxValue){
maxValue=entry.getValue();
maxEntry=entry;
}
}
tempMap.remove(maxEntry.getKey());
sortedOutputMap.put(maxEntry.getKey(),maxEntry.getValue());
}
inputUnsortedMap是代码的输入。
变量sortedOutputMap将在迭代时按降序包含数据。要更改顺序,只需在if语句中将>更改为<。
不是最快的排序,但可以在没有任何附加依赖项的情况下完成任务。
其他回答
public class Test {
public static void main(String[] args) {
TreeMap<Integer, String> hm=new TreeMap();
hm.put(3, "arun singh");
hm.put(5, "vinay singh");
hm.put(1, "bandagi singh");
hm.put(6, "vikram singh");
hm.put(2, "panipat singh");
hm.put(28, "jakarta singh");
ArrayList<String> al=new ArrayList(hm.values());
Collections.sort(al, new myComparator());
System.out.println("//sort by values \n");
for(String obj: al){
for(Map.Entry<Integer, String> map2:hm.entrySet()){
if(map2.getValue().equals(obj)){
System.out.println(map2.getKey()+" "+map2.getValue());
}
}
}
}
}
class myComparator implements Comparator{
@Override
public int compare(Object o1, Object o2) {
String o3=(String) o1;
String o4 =(String) o2;
return o3.compareTo(o4);
}
}
输出,输出=
//sort by values
3 arun singh
1 bandagi singh
28 jakarta singh
2 panipat singh
6 vikram singh
5 vinay singh
如果没有大于地图大小的值,可以使用数组,这应该是最快的方法:
public List<String> getList(Map<String, Integer> myMap) {
String[] copyArray = new String[myMap.size()];
for (Entry<String, Integer> entry : myMap.entrySet()) {
copyArray[entry.getValue()] = entry.getKey();
}
return Arrays.asList(copyArray);
}
使用java.util.TreeMap。
映射根据其键的自然顺序进行排序,或由创建映射时提供的Comparator进行排序,具体取决于使用的构造函数
使用LinkedList
//Create a list by HashMap
List<Map.Entry<String, Double>> list = new LinkedList<>(hashMap.entrySet());
//Sorting the list
Collections.sort(list, new Comparator<Map.Entry<String, Double>>() {
public int compare(Map.Entry<String, Double> o1, Map.Entry<String, Double> o2) {
return (o1.getValue()).compareTo(o2.getValue());
}
});
//put data from sorted list to hashmap
HashMap<String, Double> sortedData = new LinkedHashMap<>();
for (Map.Entry<String, Double> data : list) {
sortedData.put(data.getKey(), data.getValue());
}
System.out.print(sortedData);
Java 8提供了一个新的答案:将条目转换为流,并使用Map中的比较器组合符。条目:
Stream<Map.Entry<K,V>> sorted =
map.entrySet().stream()
.sorted(Map.Entry.comparingByValue());
这将允许您使用按值升序排序的条目。如果您想要递减值,只需反转比较器:
Stream<Map.Entry<K,V>> sorted =
map.entrySet().stream()
.sorted(Collections.reverseOrder(Map.Entry.comparingByValue()));
如果这些值不可比较,则可以传递显式比较器:
Stream<Map.Entry<K,V>> sorted =
map.entrySet().stream()
.sorted(Map.Entry.comparingByValue(comparator));
然后,您可以继续使用其他流操作来使用数据。例如,如果要在新地图中显示前10名:
Map<K,V> topTen =
map.entrySet().stream()
.sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
.limit(10)
.collect(Collectors.toMap(
Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
上面看到的LinkedHashMap按插入顺序迭代条目。
或打印到System.out:
map.entrySet().stream()
.sorted(Map.Entry.comparingByValue())
.forEach(System.out::println);