排序地图<键值,按值(Java)

问题:

我对Java比较新,经常发现我需要对值进行排序Map<Key, Value>。由于值不是唯一的,我发现自己将keySet转换为array,并且通过数组排序对该数组进行排序,并使用与该键关联的值进行排序的定制比较器。有更简单的方法吗?

回答:

这是一个通用的版本,您可以免费使用:

import java.util.*;

public class MapUtil {
    public static <K, V extends Comparable<? super V>> Map<K, V> 
        sortByValue(Map<K, V> map) {
        List<Map.Entry<K, V>> list = new LinkedList<Map.Entry<K, V>>(map.entrySet());
        Collections.sort( list, new Comparator<Map.Entry<K, V>>() {
            public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) {
                return (o1.getValue()).compareTo( o2.getValue() );
            }
        });

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

和一个相关的JUnit4测试,所以你不必为我的话说:

import java.util.*;
import org.junit.*;

public class MapUtilTest {
    @Test
    public void testSortByValue() {
        Random random = new Random(System.currentTimeMillis());
        Map<String, Integer> testMap = new HashMap<String, Integer>(1000);
        for(int i = 0; i < 1000; ++i) {
            testMap.put( "SomeString" + random.nextInt(), random.nextInt());
        }

        testMap = MapUtil.sortByValue(testMap);
        Assert.assertEquals(1000, testMap.size());

        Integer previous = null;
        for(Map.Entry<String, Integer> entry : testMap.entrySet()) {
            Assert.assertNotNull(entry.getValue());
            if (previous != null) {
                Assert.assertTrue(entry.getValue() >= previous);
            }
            previous = entry.getValue();
        }
    }
}

Java 7版本

public static <K, V extends Comparable<? super V>> Map<K, V> 
    sortByValue(Map<K, V> map) {
    List<Map.Entry<K, V>> list = new LinkedList<>(map.entrySet());
    Collections.sort( list, new Comparator<Map.Entry<K, V>>() {
        @Override
        public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) {
            return (o1.getValue()).compareTo(o2.getValue());
        }
    });

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

Java 8版本。这将按照升序排序;为了降序,只需取消对Collections.reverseOrder()的呼叫,

public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) {
    return map.entrySet()
              .stream()
              .sorted(Map.Entry.comparingByValue(/*Collections.reverseOrder()*/))
              .collect(Collectors.toMap(
                Map.Entry::getKey, 
                Map.Entry::getValue, 
                (e1, e2) -> e1, 
                LinkedHashMap::new
              ));
}

还有一种用于按值排序HashMap的技术。在这里,不使用比较器。我们根据键,交换键和值进行排序,根据值进行排序,并再次交换以获取finalMap,这是基于值排序的HashMap。

 private static LinkedHashMap<String, String> method1(HashMap<String, String> originalHashMap) {
        LinkedHashMap<String, String> sortedHashMapByKeys = new LinkedHashMap<>(); //maintains the order of putting
        TreeMap<String, String> originalTreeMap = new TreeMap<>(originalHashMap); //sorts based on keys
        for (Map.Entry<String, String> map: originalTreeMap.entrySet()) {
            sortedHashMapByKeys.put(map.getKey(), map.getValue());
        }

        LinkedHashMap<String, String> reversedOfSortedLinkedHashMap = new LinkedHashMap<>();
        for (Map.Entry<String, String> map: sortedHashMapByKeys.entrySet()) {
            reversedOfSortedLinkedHashMap.put(map.getValue(), map.getKey());
        }

        LinkedHashMap<String, String> finalMap = new LinkedHashMap<>();
        TreeMap<String, String> treeMapOfReversedOfSortedLinkedHashMap = new TreeMap<>(reversedOfSortedLinkedHashMap);
        for (Map.Entry<String, String> map: treeMapOfReversedOfSortedLinkedHashMap.entrySet()) {
            finalMap.put(map.getKey(), map.getValue()); //sort and swap
        }
        return finalMap;
    }

 
 
Code问答: http://codewenda.com/topics/python/
Stackoverflow: Sort a Map by values (Java)

*转载请注明本文链接以及stackoverflow的英文链接

发表评论

电子邮件地址不会被公开。 必填项已用*标注

74 + = 75