我对Java比较陌生,经常发现需要对值进行Map<Key,Value>排序。
由于这些值不是唯一的,我发现自己将keySet转换为一个数组,并使用自定义比较器通过数组排序对该数组进行排序,该比较器根据与该键关联的值进行排序。
有没有更简单的方法?
我对Java比较陌生,经常发现需要对值进行Map<Key,Value>排序。
由于这些值不是唯一的,我发现自己将keySet转换为一个数组,并使用自定义比较器通过数组排序对该数组进行排序,该比较器根据与该键关联的值进行排序。
有没有更简单的方法?
当前回答
这里有一个OO解决方案(即,不使用静态方法):
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class SortableValueMap<K, V extends Comparable<V>>
extends LinkedHashMap<K, V> {
public SortableValueMap() { }
public SortableValueMap( Map<K, V> map ) {
super( map );
}
public void sortByValue() {
List<Map.Entry<K, V>> list = new LinkedList<Map.Entry<K, V>>( entrySet() );
Collections.sort( list, new Comparator<Map.Entry<K, V>>() {
public int compare( Map.Entry<K, V> entry1, Map.Entry<K, V> entry2 ) {
return entry1.getValue().compareTo( entry2.getValue() );
}
});
clear();
for( Map.Entry<K, V> entry : list ) {
put( entry.getKey(), entry.getValue() );
}
}
private static void print( String text, Map<String, Double> map ) {
System.out.println( text );
for( String key : map.keySet() ) {
System.out.println( "key/value: " + key + "/" + map.get( key ) );
}
}
public static void main( String[] args ) {
SortableValueMap<String, Double> map =
new SortableValueMap<String, Double>();
map.put( "A", 67.5 );
map.put( "B", 99.5 );
map.put( "C", 82.4 );
map.put( "D", 42.0 );
print( "Unsorted map", map );
map.sortByValue();
print( "Sorted map", map );
}
}
特此捐赠给公共领域。
其他回答
创建自定义比较器,并在创建新的TreeMap对象时使用它。
class MyComparator implements Comparator<Object> {
Map<String, Integer> map;
public MyComparator(Map<String, Integer> map) {
this.map = map;
}
public int compare(Object o1, Object o2) {
if (map.get(o2) == map.get(o1))
return 1;
else
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", 75);
lMap.put("C", 50);
lMap.put("D", 50);
MyComparator comparator = new MyComparator(lMap);
Map<String, Integer> newMap = new TreeMap<String, Integer>(comparator);
newMap.putAll(lMap);
System.out.println(newMap);
输出:
{B=75, D=50, C=50, A=35}
因为地图是无序的要对其进行排序,我们可以执行以下操作
Map<String, String> map= new TreeMap<String, String>(unsortMap);
您应该注意,与哈希映射不同,树映射保证其元素将按升序键排序。
Geeks For Geeks对HashMap按值排序
Input : Key = Math, Value = 98
Key = Data Structure, Value = 85
Key = Database, Value = 91
Key = Java, Value = 95
Key = Operating System, Value = 79
Key = Networking, Value = 80
Output : Key = Operating System, Value = 79
Key = Networking, Value = 80
Key = Data Structure, Value = 85
Key = Database, Value = 91
Key = Java, Value = 95
Key = Math, Value = 98
Solution: The idea is to store the entry set in a list and sort the list on the basis of values. Then fetch values and keys from the list and put them in a new hashmap. Thus, a new hashmap is sorted according to values.
Below is the implementation of the above idea:
// Java program to sort hashmap by values
import java.util.*;
import java.lang.*;
public class GFG {
// function to sort hashmap by values
public static HashMap<String, Integer> sortByValue(HashMap<String, Integer> hm)
{
// Create a list from elements of HashMap
List<Map.Entry<String, Integer> > list =
new LinkedList<Map.Entry<String, Integer> >(hm.entrySet());
// Sort the list
Collections.sort(list, new Comparator<Map.Entry<String, Integer> >() {
public int compare(Map.Entry<String, Integer> o1,
Map.Entry<String, Integer> o2)
{
return (o1.getValue()).compareTo(o2.getValue());
}
});
// put data from sorted list to hashmap
HashMap<String, Integer> temp = new LinkedHashMap<String, Integer>();
for (Map.Entry<String, Integer> aa : list) {
temp.put(aa.getKey(), aa.getValue());
}
return temp;
}
// Driver Code
public static void main(String[] args)
{
HashMap<String, Integer> hm = new HashMap<String, Integer>();
// enter data into hashmap
hm.put("Math", 98);
hm.put("Data Structure", 85);
hm.put("Database", 91);
hm.put("Java", 95);
hm.put("Operating System", 79);
hm.put("Networking", 80);
Map<String, Integer> hm1 = sortByValue(hm);
// print the sorted hashmap
for (Map.Entry<String, Integer> en : hm1.entrySet()) {
System.out.println("Key = " + en.getKey() +
", Value = " + en.getValue());
}
}
}
Output
Key = Operating System, Value = 79
Key = Networking, Value = 80
Key = Data Structure, Value = 85
Key = Database, Value = 91
Key = Java, Value = 95
Key = Math, Value = 98
从…起http://www.programmersheaven.com/download/49349/download.aspx
private static <K, V> Map<K, V> sortByValue(Map<K, V> map) {
List<Entry<K, V>> list = new LinkedList<>(map.entrySet());
Collections.sort(list, new Comparator<Object>() {
@SuppressWarnings("unchecked")
public int compare(Object o1, Object o2) {
return ((Comparable<V>) ((Map.Entry<K, V>) (o1)).getValue()).compareTo(((Map.Entry<K, V>) (o2)).getValue());
}
});
Map<K, V> result = new LinkedHashMap<>();
for (Iterator<Entry<K, V>> it = list.iterator(); it.hasNext();) {
Map.Entry<K, V> entry = (Map.Entry<K, V>) it.next();
result.put(entry.getKey(), entry.getValue());
}
return result;
}
我认为最好的方法是使用特殊的数据结构。您可以考虑TreeMap,但在一般情况下,值可能不是唯一的。因此,您的选择是PriorityQueue:
public static <K, V> Iterator<Map.Entry<K, V>> sortByValue(
Map<K, V> map,
Comparator<V> valueComparator) {
Queue<Map.Entry<K, V>> queue = new PriorityQueue<>((one, two) ->
valueComparator.compare(one.getValue(), two.getValue()));
queue.addAll(map.entrySet());
return queue.iterator();
}