关于Java:按值对Map排序

Sort a Map<Key, Value> by values

我对Java比较新,并且经常发现需要在值上对EDCOX1 0进行排序。

由于这些值不是唯一的,所以我发现自己将keySet转换为array,并使用自定义比较器对数组进行排序,该比较器对与键相关的值进行排序。

有更简单的方法吗?


这是一个通用的友好版本:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class MapUtil {
    public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) {
        List<Entry<K, V>> list = new ArrayList<>(map.entrySet());
        list.sort(Entry.comparingByValue());

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

        return result;
    }
}


重要注意事项:

此代码可以以多种方式中断。如果您打算使用所提供的代码,请务必阅读注释并了解其含义。例如,值不能再由其键检索。(get总是返回null。)

这似乎比前面所有的都容易。使用treemap,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class Testing {
    public static void main(String[] args) {
        HashMap<String, Double> map = new HashMap<String, Double>();
        ValueComparator bvc = new ValueComparator(map);
        TreeMap<String, Double> sorted_map = new TreeMap<String, Double>(bvc);

        map.put("A", 99.5);
        map.put("B", 67.4);
        map.put("C", 67.4);
        map.put("D", 67.3);

        System.out.println("unsorted map:" + map);
        sorted_map.putAll(map);
        System.out.println("results:" + sorted_map);
    }
}

class ValueComparator implements Comparator<String> {
    Map<String, Double> base;

    public ValueComparator(Map<String, Double> base) {
        this.base = base;
    }

    // Note: this comparator imposes orderings that are inconsistent with
    // equals.
    public int compare(String a, String b) {
        if (base.get(a) >= base.get(b)) {
            return -1;
        } else {
            return 1;
        } // returning 0 would merge keys
    }
}

输出:

1
2
unsorted map: {D=67.3, A=99.5, B=67.4, C=67.4}
results: {D=67.3, B=67.4, C=67.4, A=99.5}


Java 8提供了一个新的答案:将条目转换成流,并使用来自Mava.Enter的比较器组合器:

1
2
3
Stream<Map.Entry<K,V>> sorted =
    map.entrySet().stream()
       .sorted(Map.Entry.comparingByValue());

这将允许您使用按值升序排序的条目。如果您想要递减值,只需反转比较器:

1
2
3
Stream<Map.Entry<K,V>> sorted =
    map.entrySet().stream()
       .sorted(Collections.reverseOrder(Map.Entry.comparingByValue()));

如果值不可比较,则可以传递显式比较器:

1
2
3
Stream<Map.Entry<K,V>> sorted =
    map.entrySet().stream()
       .sorted(Map.Entry.comparingByValue(comparator));

然后可以继续使用其他流操作来使用数据。例如,如果要在新地图中显示前10名:

1
2
3
4
5
6
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));

或打印到System.out

1
2
3
map.entrySet().stream()
   .sorted(Map.Entry.comparingByValue())
   .forEach(System.out::println);


三个一行答案…

我将使用Google Collections来执行此操作-如果您的值是Comparable,则可以使用

1
valueComparator = Ordering.natural().onResultOf(Functions.forMap(map))

它将为映射创建一个函数(对象)(接受任何键作为输入,返回各自的值),然后对它们应用自然(可比较)顺序[值]。

如果它们不具有可比性,那么您需要按照

1
valueComparator = Ordering.from(comparator).onResultOf(Functions.forMap(map))

这些可以应用于treemap(因为Ordering扩展了Comparator或经过某种排序的linkedhashmap

注意:如果要使用treemap,请记住,如果比较==0,则该项已在列表中(如果有多个值比较相同,则会发生这种情况)。为了减轻这种情况,您可以像这样将您的键添加到比较器中(假定您的键和值是Comparable)。

1
valueComparator = Ordering.natural().onResultOf(Functions.forMap(map)).compound(Ordering.natural())

=对键映射的值应用自然顺序,并将其与键的自然顺序复合

请注意,如果您的密钥与0比较,这仍然不起作用,但这对于大多数Comparable项(因为hashCodeequalscompareTo通常是同步的…)

请参见ordering.onResultOf()和functions.formp()。

实施

现在我们有了一个比较器,可以做我们想要做的,我们需要从中得到一个结果。

1
map = ImmutableSortedMap.copyOf(myOriginalMap, valueComparator);

现在这很有可能奏效,但是:

  • 如果有一张完整的完成的地图,就需要完成。
  • 不要在TreeMap上尝试上面的比较器;当插入的键直到Put之后才有值时,没有必要尝试比较它,也就是说,它会很快断开。
  • 第1点对我来说有点破坏协议;谷歌的收藏非常懒惰(这很好:你可以在一瞬间完成几乎所有的操作;真正的工作是在你开始使用结果时完成的),这需要复制整个地图!

    "完整"答案/按值排序的实时地图

    不过,不要担心;如果你对"实时"地图的排序非常着迷,那么你就只能解决一个问题,而只能解决两个问题!以上问题中有一些疯狂的,比如:

    注:这在2012年6月发生了显著变化-以前的代码无法工作:需要一个内部哈希映射来查找值,而不在TreeMap.get()->compare()compare()->get()之间创建无限循环。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    import static org.junit.Assert.assertEquals;

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

    import com.google.common.base.Functions;
    import com.google.common.collect.Ordering;

    class ValueComparableMap<K extends Comparable<K>,V> extends TreeMap<K,V> {
        //A map for doing lookups on the keys for comparison so we don't get infinite loops
        private final Map<K, V> valueMap;

        ValueComparableMap(final Ordering<? super V> partialValueOrdering) {
            this(partialValueOrdering, new HashMap<K,V>());
        }

        private ValueComparableMap(Ordering<? super V> partialValueOrdering,
                HashMap<K, V> valueMap) {
            super(partialValueOrdering //Apply the value ordering
                    .onResultOf(Functions.forMap(valueMap)) //On the result of getting the value for the key from the map
                    .compound(Ordering.natural())); //as well as ensuring that the keys don't get clobbered
            this.valueMap = valueMap;
        }

        public V put(K k, V v) {
            if (valueMap.containsKey(k)){
                //remove the key in the sorted set before adding the key again
                remove(k);
            }
            valueMap.put(k,v); //To get"real" unsorted values for the comparator
            return super.put(k, v); //Put it in value order
        }

        public static void main(String[] args){
            TreeMap<String, Integer> map = new ValueComparableMap<String, Integer>(Ordering.natural());
            map.put("a", 5);
            map.put("b", 1);
            map.put("c", 3);
            assertEquals("b",map.firstKey());
            assertEquals("a",map.lastKey());
            map.put("d",0);
            assertEquals("d",map.firstKey());
            //ensure it's still a map (by overwriting a key, but with a new value)
            map.put("d", 2);
            assertEquals("b", map.firstKey());
            //Ensure multiple values do not clobber keys
            map.put("e", 2);
            assertEquals(5, map.size());
            assertEquals(2, (int) map.get("e"));
            assertEquals(2, (int) map.get("d"));
        }
     }

    当我们放入时,我们确保散列映射具有比较器的值,然后放入树集进行排序。但在这之前,我们检查散列映射,以查看该键实际上不是重复的。另外,我们创建的比较器也将包含这个键,这样重复的值就不会删除不重复的键(由于==比较)。这两个项目对于确保地图合同的保存至关重要;如果您认为您不想这样做,那么您几乎就要完全反转地图了(到Map)。

    构造函数需要调用为

    1
    2
    3
     new ValueComparableMap(Ordering.natural());
     //or
     new ValueComparableMap(Ordering.from(comparator));


    从http:/ / / / / download.aspx www.programmersheaven.com下载49349P></

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    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;
    }


    使用Java 8,您可以使用流API来以一种明显不那么冗长的方式来执行它:

    1
    2
    3
    Map<K, V> sortedMap = map.entrySet().stream()
                             .sorted(Entry.comparingByValue())
                             .collect(Collectors.toMap(Entry::getKey, Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));


    sorting the Keys to the comparator……each value for each进行外观检查。解决方案:在使用黑莓scalable会entryset directly since the value,则会立即available for each比较好(尽管还没有放弃这个弹出的数字)。P></

    这是在这样一件事:Generic version ofP></

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    public static <K, V extends Comparable<? super V>> List<K> getKeysSortedByValue(Map<K, V> map) {
        final int size = map.size();
        final List<Map.Entry<K, V>> list = new ArrayList<Map.Entry<K, V>>(size);
        list.addAll(map.entrySet());
        final ValueComparator<V> cmp = new ValueComparator<V>();
        Collections.sort(list, cmp);
        final List<K> keys = new ArrayList<K>(size);
        for (int i = 0; i < size; i++) {
            keys.set(i, list.get(i).getKey());
        }
        return keys;
    }

    private static final class ValueComparator<V extends Comparable<? super V>>
                                         implements Comparator<Map.Entry<?, V>> {
        public int compare(Map.Entry<?, V> o1, Map.Entry<?, V> o2) {
            return o1.getValue().compareTo(o2.getValue());
        }
    }

    there are for the rotation lessen方式存储到上述解决方案。created the ArrayList可以换好第一审used as a王-这会返回值;require of some泛型WARNINGS消,but for?可能值得它可重复使用库代码。also does not have to,the comparator嗯-在每一invocation allocated国王。P></

    但少有更高效appealing版本:P></

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public static <K, V extends Comparable<? super V>> List<K> getKeysSortedByValue2(Map<K, V> map) {
        final int size = map.size();
        final List reusedList = new ArrayList(size);
        final List<Map.Entry<K, V>> meView = reusedList;
        meView.addAll(map.entrySet());
        Collections.sort(meView, SINGLE);
        final List<K> keyView = reusedList;
        for (int i = 0; i < size; i++) {
            keyView.set(i, meView.get(i).getKey());
        }
        return keyView;
    }

    private static final Comparator SINGLE = new ValueComparator();

    最后,if You need to the continously接入类信息(比一盎司sorting Rather恩段),你可以使用额外的地图也多。让我知道如果你需要更多的细节。P></


    我已经看过给定的答案,但是其中很多比需要的要复杂,或者当几个键具有相同的值时删除映射元素。

    以下是我认为更适合的解决方案:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public static <K, V extends Comparable<V>> Map<K, V> sortByValues(final Map<K, V> map) {
        Comparator<K> valueComparator =  new Comparator<K>() {
            public int compare(K k1, K k2) {
                int compare = map.get(k2).compareTo(map.get(k1));
                if (compare == 0) return 1;
                else return compare;
            }
        };
        Map<K, V> sortedByValues = new TreeMap<K, V>(valueComparator);
        sortedByValues.putAll(map);
        return sortedByValues;
    }

    请注意,映射是从最高值到最低值排序的。


    在collections contains the Commons -所谓的treebidimap图书馆解决方案。或者,你可以有一个collections look at the Google API。你可以使用它treemultimap which has。P></

    如果你不想使用这些框架。如何与他们的源代码。P></


    用Java 8中的新特性来实现这一点:

    1
    2
    3
    4
    5
    6
    import static java.util.Map.Entry.comparingByValue;
    import static java.util.stream.Collectors.toList;

    <K, V> List<Entry<K, V>> sort(Map<K, V> map, Comparator<? super V> comparator) {
        return map.entrySet().stream().sorted(comparingByValue(comparator)).collect(toList());
    }

    这些条目使用给定的比较器按其值排序。或者,如果您的值相互比较,则不需要显式的比较器:

    1
    2
    3
    <K, V extends Comparable<? super V>> List<Entry<K, V>> sort(Map<K, V> map) {
        return map.entrySet().stream().sorted(comparingByValue()).collect(toList());
    }

    返回的列表是调用此方法时给定映射的快照,因此两者都不会反映对另一个方法的后续更改。对于地图的实时不可见视图:

    1
    2
    3
    <K, V extends Comparable<? super V>> Iterable<Entry<K, V>> sort(Map<K, V> map) {
        return () -> map.entrySet().stream().sorted(comparingByValue()).iterator();
    }

    返回的iterable每次迭代时都会为给定映射创建一个新的快照,因此除非进行并发修改,否则它将始终反映映射的当前状态。


    创建定制的比较器,并在创建新的treemap对象时使用它。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    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));

        }
    }

    在主函数中使用以下代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
        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);

    输出:

    1
    {B=75, D=50, C=50, A=35}


    我同意that the constant is probably need to sort在映射到队列的味道,我想easiest the following is the Way to do without using a different /数据结构。P></

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public class MapUtilities {

    public static <K, V extends Comparable<V>> List<Entry<K, V>> sortByValue(Map<K, V> map) {
        List<Entry<K, V>> entries = new ArrayList<Entry<K, V>>(map.entrySet());
        Collections.sort(entries, new ByValue<K, V>());
        return entries;
    }

    private static class ByValue<K, V extends Comparable<V>> implements Comparator<Entry<K, V>> {
        public int compare(Entry<K, V> o1, Entry<K, V> o2) {
            return o1.getValue().compareTo(o2.getValue());
        }
    }

    }P></

    这里是不完整和安embarrassingly:单元测试P></

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public class MapUtilitiesTest extends TestCase {
    public void testSorting() {
        HashMap<String, Integer> map = new HashMap<String, Integer>();
        map.put("One", 1);
        map.put("Two", 2);
        map.put("Three", 3);

        List<Map.Entry<String, Integer>> sorted = MapUtilities.sortByValue(map);
        assertEquals("First","One", sorted.get(0).getKey());
        assertEquals("Second","Two", sorted.get(1).getKey());
        assertEquals("Third","Three", sorted.get(2).getKey());
    }

    }P></

    the result is a list of entry对象映射类,from which。You can obtain the keys的布尔值。P></


    使用通用比较器,如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    final class MapValueComparator<K,V extends Comparable<V>> implements Comparator<K> {

        private Map<K,V> map;

        private MapValueComparator() {
            super();
        }

        public MapValueComparator(Map<K,V> map) {
            this();
            this.map = map;
        }

        public int compare(K o1, K o2) {
            return map.get(o1).compareTo(map.get(o2));
        }
    }

    当你有两个相等的项目时,投给大多数人的答案不起作用。treemap会留下相等的值。

    Expple:未排序地图

    1
    2
    3
    4
    5
    key/value: D/67.3
    key/value: A/99.5
    key/value: B/67.4
    key/value: C/67.5
    key/value: E/99.5

    结果

    1
    2
    3
    4
    key/value: A/99.5
    key/value: C/67.5
    key/value: B/67.4
    key/value: D/67.3

    所以不考虑E!!

    对我来说,调整比较器很好,如果它等于,就不要返回0,而是-1。

    在例子中:

    class ValueComparator implements Comparator {

    Map base;
    public ValueComparator(Map base) {
    this.base = base;
    }

    public int compare(Object a, Object b) {

    1
    2
    3
    4
    5
    6
    7
    if((Double)base.get(a) < (Double)base.get(b)) {
      return 1;
    } else if((Double)base.get(a) == (Double)base.get(b)) {
      return -1;
    } else {
      return -1;
    }

    }
    }

    < /块引用>

    现在它回来了:

    未排序地图:

    1
    2
    3
    4
    5
    key/value: D/67.3
    key/value: A/99.5
    key/value: B/67.4
    key/value: C/67.5
    key/value: E/99.5

    结果:

    1
    2
    3
    4
    5
    key/value: A/99.5
    key/value: E/99.5
    key/value: C/67.5
    key/value: B/67.4
    key/value: D/67.3

    作为对外国人的回应(2011年11月22日):我正在使用此解决方案对整数ID和名称的映射进行处理,但想法是相同的,因此上面的代码可能不正确(我将在测试中编写它并给您正确的代码),这是基于上述解决方案的映射排序代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    package nl.iamit.util;

    import java.util.Comparator;
    import java.util.Map;

    public class Comparators {


        public static class MapIntegerStringComparator implements Comparator {

            Map<Integer, String> base;

            public MapIntegerStringComparator(Map<Integer, String> base) {
                this.base = base;
            }

            public int compare(Object a, Object b) {

                int compare = ((String) base.get(a))
                        .compareTo((String) base.get(b));
                if (compare == 0) {
                    return -1;
                }
                return compare;
            }
        }


    }

    这是测试类(我刚刚测试过它,它适用于整数,字符串映射:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    package test.nl.iamit.util;

    import java.util.HashMap;
    import java.util.TreeMap;
    import nl.iamit.util.Comparators;
    import org.junit.Test;
    import static org.junit.Assert.assertArrayEquals;

    public class TestComparators {


        @Test
        public void testMapIntegerStringComparator(){
            HashMap<Integer, String> unSoretedMap = new HashMap<Integer, String>();
            Comparators.MapIntegerStringComparator bvc = new Comparators.MapIntegerStringComparator(
                    unSoretedMap);
            TreeMap<Integer, String> sorted_map = new TreeMap<Integer, String>(bvc);
            //the testdata:
            unSoretedMap.put(new Integer(1),"E");
            unSoretedMap.put(new Integer(2),"A");
            unSoretedMap.put(new Integer(3),"E");
            unSoretedMap.put(new Integer(4),"B");
            unSoretedMap.put(new Integer(5),"F");

            sorted_map.putAll(unSoretedMap);

            Object[] targetKeys={new Integer(2),new Integer(4),new Integer(3),new Integer(1),new Integer(5) };
            Object[] currecntKeys=sorted_map.keySet().toArray();

            assertArrayEquals(targetKeys,currecntKeys);
        }
    }

    下面是地图比较器的代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    public static class MapStringDoubleComparator implements Comparator {

        Map<String, Double> base;

        public MapStringDoubleComparator(Map<String, Double> base) {
            this.base = base;
        }

        //note if you want decending in stead of ascending, turn around 1 and -1
        public int compare(Object a, Object b) {
            if ((Double) base.get(a) == (Double) base.get(b)) {
                return 0;
            } else if((Double) base.get(a) < (Double) base.get(b)) {
                return -1;
            }else{
                return 1;
            }
        }
    }

    这就是这个的测试案例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    @Test
    public void testMapStringDoubleComparator(){
        HashMap<String, Double> unSoretedMap = new HashMap<String, Double>();
        Comparators.MapStringDoubleComparator bvc = new Comparators.MapStringDoubleComparator(
                unSoretedMap);
        TreeMap<String, Double> sorted_map = new TreeMap<String, Double>(bvc);
        //the testdata:
        unSoretedMap.put("D",new Double(67.3));
        unSoretedMap.put("A",new Double(99.5));
        unSoretedMap.put("B",new Double(67.4));
        unSoretedMap.put("C",new Double(67.5));
        unSoretedMap.put("E",new Double(99.5));

        sorted_map.putAll(unSoretedMap);

        Object[] targetKeys={"D","B","C","E","A
    <div class="
    suo-content">[collapse title=""]<ul><li>这不适合我。我得到了所有的价值。</li><li>你是对的,我给你的密码有一些错误!我希望我最近的版本能帮助你。</li></ul>[/collapse]</div><p><center>[wp_ad_camp_2]</center></p><hr><P>我建议不要像某些人那样使用<wyn>Collections.sort</wyn>,而是使用<wyn>Arrays.sort</wyn>。实际上,<wyn>Collections.sort</wyn>所做的就是这样:</P>[cc lang="java"]public static <T extends Comparable<? super T>> void sort(List<T> list) {
        Object[] a = list.toArray();
        Arrays.sort(a);
        ListIterator<T> i = list.listIterator();
        for (int j=0; j<a.length; j++) {
            i.next();
            i.set((T)a[j]);
        }
    }

    它只是在列表中调用toArray,然后使用Arrays.sort。这样,所有映射条目将被复制三次:一次从映射复制到临时列表(无论是LinkedList还是ArrayList),然后复制到临时数组,最后复制到新映射。

    我的解决方案建议这一步,因为它不会创建不必要的LinkedList。下面是代码,通用友好,性能最佳:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map)
    {
        @SuppressWarnings("unchecked")
        Map.Entry<K,V>[] array = map.entrySet().toArray(new Map.Entry[map.size()]);

        Arrays.sort(array, new Comparator<Map.Entry<K, V>>()
        {
            public int compare(Map.Entry<K, V> e1, Map.Entry<K, V> e2)
            {
                return e1.getValue().compareTo(e2.getValue());
            }
        });

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

        return result;
    }

    这是安东尼答案的变体,如果存在重复的值,则不起作用:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    public static <K, V extends Comparable<V>> Map<K, V> sortMapByValues(final Map<K, V> map) {
        Comparator<K> valueComparator =  new Comparator<K>() {
            public int compare(K k1, K k2) {
                final V v1 = map.get(k1);
                final V v2 = map.get(k2);

                /* Not sure how to handle nulls ... */
                if (v1 == null) {
                    return (v2 == null) ? 0 : 1;
                }

                int compare = v2.compareTo(v1);
                if (compare != 0)
                {
                    return compare;
                }
                else
                {
                    Integer h1 = k1.hashCode();
                    Integer h2 = k2.hashCode();
                    return h2.compareTo(h1);
                }
            }
        };
        Map<K, V> sortedByValues = new TreeMap<K, V>(valueComparator);
        sortedByValues.putAll(map);
        return sortedByValues;
    }

    请注意,如何处理空值是相当悬而未决的。

    这种方法的一个重要优点是它实际上返回一个映射,与这里提供的其他一些解决方案不同。


    主要问题。如果您使用第一个答案(Google将您带到这里),请更改Comparator以添加一个equal子句,否则您将无法从按键排序的_映射中获取值:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public int compare(String a, String b) {
            if (base.get(a) > base.get(b)) {
                return 1;
            } else if (base.get(a) < base.get(b)){
                return -1;
            }

            return 0;
            // returning 0 would merge keys
        }


    最佳途径

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Comparator;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.Set;
    import java.util.Map.Entry;

    public class OrderByValue {

      public static void main(String a[]){
        Map<String, Integer> map = new HashMap<String, Integer>();
        map.put("java", 20);
        map.put("C++", 45);
        map.put("Unix", 67);
        map.put("MAC", 26);
        map.put("Why this kolavari", 93);
        Set<Entry<String, Integer>> set = map.entrySet();
        List<Entry<String, Integer>> list = new ArrayList<Entry<String, Integer>>(set);
        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() );//Ascending order
                //return (o2.getValue()).compareTo( o1.getValue() );//Descending order
            }
        } );
        for(Map.Entry<String, Integer> entry:list){
            System.out.println(entry.getKey()+" ===="+entry.getValue());
        }
      }}

    产量

    1
    2
    3
    4
    5
    6
    7
    8
    9
    java ==== 20

    MAC ==== 26

    C++ ==== 45

    Unix ==== 67

    Why this kolavari ==== 93

    对于这个问题已经有很多答案了,但是没有一个提供了我正在寻找的东西,一个映射实现返回按关联值排序的键和条目,并在映射中修改键和值时维护这个属性。另外还有两个问题专门问这个问题。

    我编写了一个通用的友好示例来解决这个用例。此实现不符合映射接口的所有约定,例如,在原始对象中反映从keyset()和entryset()返回的集合中的值更改和删除。我觉得这样的解决方案太大,无法包含在堆栈溢出答案中。如果我设法创建一个更完整的实现,也许我会将它发布到Github,然后链接到这个答案的更新版本中。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    import java.util.*;

    /**
     * A map where {@link #keySet()} and {@link #entrySet()} return sets ordered
     * by associated values based on the the comparator provided at construction
     * time. The order of two or more keys with identical values is not defined.
     * <p>

     * Several contracts of the Map interface are not satisfied by this minimal
     * implementation.
     */

    public class ValueSortedMap<K, V> extends HashMap<K, V> {
        protected Map<V, Collection<K>> valueToKeysMap;

        // uses natural order of value object, if any
        public ValueSortedMap() {
            this((Comparator<? super V>) null);
        }

        public ValueSortedMap(Comparator<? super V> valueComparator) {
            this.valueToKeysMap = new TreeMap<V, Collection<K>>(valueComparator);
        }

        public boolean containsValue(Object o) {
            return valueToKeysMap.containsKey(o);
        }

        public V put(K k, V v) {
            V oldV = null;
            if (containsKey(k)) {
                oldV = get(k);
                valueToKeysMap.get(oldV).remove(k);
            }
            super.put(k, v);
            if (!valueToKeysMap.containsKey(v)) {
                Collection<K> keys = new ArrayList<K>();
                keys.add(k);
                valueToKeysMap.put(v, keys);
            } else {
                valueToKeysMap.get(v).add(k);
            }
            return oldV;
        }

        public void putAll(Map<? extends K, ? extends V> m) {
            for (Map.Entry<? extends K, ? extends V> e : m.entrySet())
                put(e.getKey(), e.getValue());
        }

        public V remove(Object k) {
            V oldV = null;
            if (containsKey(k)) {
                oldV = get(k);
                super.remove(k);
                valueToKeysMap.get(oldV).remove(k);
            }
            return oldV;
        }

        public void clear() {
            super.clear();
            valueToKeysMap.clear();
        }

        public Set<K> keySet() {
            LinkedHashSet<K> ret = new LinkedHashSet<K>(size());
            for (V v : valueToKeysMap.keySet()) {
                Collection<K> keys = valueToKeysMap.get(v);
                ret.addAll(keys);
            }
            return ret;
        }

        public Set<Map.Entry<K, V>> entrySet() {
            LinkedHashSet<Map.Entry<K, V>> ret = new LinkedHashSet<Map.Entry<K, V>>(size());
            for (Collection<K> keys : valueToKeysMap.values()) {
                for (final K k : keys) {
                    final V v = get(k);
                    ret.add(new Map.Entry<K,V>() {
                        public K getKey() {
                            return k;
                        }

                        public V getValue() {
                            return v;
                        }

                        public V setValue(V v) {
                            throw new UnsupportedOperationException();
                        }
                    });
                }
            }
            return ret;
        }
    }

    depending on the context,java.util.LinkedHashMapwhich using the which items are rememebers阶placed into the map。如果You need to sort otherwise,基于序值,他们自然会recommend,which can be维持在单独的列表Collections.sort()类路径。P></


    由于treemap<>不适用于可以相等的值,因此我使用了以下方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    private <K, V extends Comparable<? super V>> List<Entry<K, V>> sort(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());
            }
        });

        return list;
    }

    你可能想把这个列表放到Linkedhashmap中,但是如果你只想马上遍历它,那就太多余了…


    这太复杂了。地图不应该像按值排序那样做。最简单的方法是创建自己的类,以便它符合您的需求。

    在下面的示例中,您应该在*所在的位置添加一个比较器treemap。但是通过Java API,它只给出了比较器的键,而不是值。此处所述的所有示例均基于2个地图。一个哈希和一个新树。真奇怪。

    例子:

    1
    Map<Driver driver, Float time> map = new TreeMap<Driver driver, Float time>(*);

    所以把地图改成这样一个集合:

    1
    2
    ResultComparator rc = new ResultComparator();
    Set<Results> set = new TreeSet<Results>(rc);

    您将创建类Results

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    public class Results {
        private Driver driver;
        private Float time;

        public Results(Driver driver, Float time) {
            this.driver = driver;
            this.time = time;
        }

        public Float getTime() {
            return time;
        }

        public void setTime(Float time) {
            this.time = time;
        }

        public Driver getDriver() {
            return driver;
        }

        public void setDriver (Driver driver) {
            this.driver = driver;
        }
    }

    比较器类:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class ResultsComparator implements Comparator<Results> {
        public int compare(Results t, Results t1) {
            if (t.getTime() < t1.getTime()) {
                return 1;
            } else if (t.getTime() == t1.getTime()) {
                return 0;
            } else {
                return -1;
            }
        }
    }

    这样您就可以轻松地添加更多的依赖项。

    最后一点,我将添加简单的迭代器:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    Iterator it = set.iterator();
    while (it.hasNext()) {
        Results r = (Results)it.next();
        System.out.println( r.getDriver().toString
            //or whatever that is related to Driver class -getName() getSurname()
            +""
            + r.getTime()
            );
    }

    Afaik最干净的方法是利用集合按值对地图进行排序:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    Map<String, Long> map = new HashMap<String, Long>();
    // populate with data to sort on Value
    // use datastructure designed for sorting

    Queue queue = new PriorityQueue( map.size(), new MapComparable() );
    queue.addAll( map.entrySet() );

    // get a sorted map
    LinkedHashMap<String, Long> linkedMap = new LinkedHashMap<String, Long>();

    for (Map.Entry<String, Long> entry; (entry = queue.poll())!=null;) {
        linkedMap.put(entry.getKey(), entry.getValue());
    }

    public static class MapComparable implements Comparator<Map.Entry<String, Long>>{

      public int compare(Entry<String, Long> e1, Entry<String, Long> e2) {
        return e1.getValue().compareTo(e2.getValue());
      }
    }

    基于图sorting @ devinmoore队列,使用泛型方法和支持都ascending和descending序。P></

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    /**
     * Sort a map by it's keys in ascending order.
     *  
     * @return new instance of {@link LinkedHashMap} contained sorted entries of supplied map.
     * @author Maxim Veksler
     */

    public static <K, V> LinkedHashMap<K, V> sortMapByKey(final Map<K, V> map) {
        return sortMapByKey(map, SortingOrder.ASCENDING);
    }

    /**
     * Sort a map by it's values in ascending order.
     *  
     * @return new instance of {@link LinkedHashMap} contained sorted entries of supplied map.
     * @author Maxim Veksler
     */

    public static <K, V> LinkedHashMap<K, V> sortMapByValue(final Map<K, V> map) {
        return sortMapByValue(map, SortingOrder.ASCENDING);
    }

    /**
     * Sort a map by it's keys.
     *  
     * @param sortingOrder {@link SortingOrder} enum specifying requested sorting order.
     * @return new instance of {@link LinkedHashMap} contained sorted entries of supplied map.
     * @author Maxim Veksler
     */

    public static <K, V> LinkedHashMap<K, V> sortMapByKey(final Map<K, V> map, final SortingOrder sortingOrder) {
        Comparator<Map.Entry<K, V>> comparator = new Comparator<Entry<K,V>>() {
            public int compare(Entry<K, V> o1, Entry<K, V> o2) {
                return comparableCompare(o1.getKey(), o2.getKey(), sortingOrder);
            }
        };

        return sortMap(map, comparator);
    }

    /**
     * Sort a map by it's values.
     *  
     * @param sortingOrder {@link SortingOrder} enum specifying requested sorting order.
     * @return new instance of {@link LinkedHashMap} contained sorted entries of supplied map.
     * @author Maxim Veksler
     */

    public static <K, V> LinkedHashMap<K, V> sortMapByValue(final Map<K, V> map, final SortingOrder sortingOrder) {
        Comparator<Map.Entry<K, V>> comparator = new Comparator<Entry<K,V>>() {
            public int compare(Entry<K, V> o1, Entry<K, V> o2) {
                return comparableCompare(o1.getValue(), o2.getValue(), sortingOrder);
            }
        };

        return sortMap(map, comparator);
    }

    @SuppressWarnings("unchecked")
    private static <T> int comparableCompare(T o1, T o2, SortingOrder sortingOrder) {
        int compare = ((Comparable<T>)o1).compareTo(o2);

        switch (sortingOrder) {
        case ASCENDING:
            return compare;
        case DESCENDING:
            return (-1) * compare;
        }

        return 0;
    }

    /**
     * Sort a map by supplied comparator logic.
     *  
     * @return new instance of {@link LinkedHashMap} contained sorted entries of supplied map.
     * @author Maxim Veksler
     */

    public static <K, V> LinkedHashMap<K, V> sortMap(final Map<K, V> map, final Comparator<Map.Entry<K, V>> comparator) {
        // Convert the map into a list of key,value pairs.
        List<Map.Entry<K, V>> mapEntries = new LinkedList<Map.Entry<K, V>>(map.entrySet());

        // Sort the converted list according to supplied comparator.
        Collections.sort(mapEntries, comparator);

        // Build a new ordered map, containing the same entries as the old map.  
        LinkedHashMap<K, V> result = new LinkedHashMap<K, V>(map.size() + (map.size() / 20));
        for(Map.Entry<K, V> entry : mapEntries) {
            // We iterate on the mapEntries list which is sorted by the comparator putting new entries into
            // the targeted result which is a sorted map.
            result.put(entry.getKey(), entry.getValue());
        }

        return result;
    }

    /**
     * Sorting order enum, specifying request result sort behavior.
     * @author Maxim Veksler
     *
     */

    public static enum SortingOrder {
        /**
         * Resulting sort will be from smaller to biggest.
         */

        ASCENDING,
        /**
         * Resulting sort will be from biggest to smallest.
         */

        DESCENDING
    }


    这里有一个OO解决方案(即不使用static方法):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    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 );
      }
    }

    特此捐赠给公共领域。


    当然,斯蒂芬的解决方案非常好,但对于那些不能使用番石榴的人来说:

    这是按值排序地图的解决方案。这个解决方案处理的情况下,有两个相同的价值等。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    // If you want to sort a map by value, and if there can be twice the same value:

    // here is your original map
    Map<String,Integer> mapToSortByValue = new HashMap<String, Integer>();
    mapToSortByValue.put("A", 3);
    mapToSortByValue.put("B", 1);
    mapToSortByValue.put("C", 3);
    mapToSortByValue.put("D", 5);
    mapToSortByValue.put("E", -1);
    mapToSortByValue.put("F", 1000);
    mapToSortByValue.put("G", 79);
    mapToSortByValue.put("H", 15);

    // Sort all the map entries by value
    Set<Map.Entry<String,Integer>> set = new TreeSet<Map.Entry<String,Integer>>(
            new Comparator<Map.Entry<String,Integer>>(){
                @Override
                public int compare(Map.Entry<String,Integer> obj1, Map.Entry<String,Integer> obj2) {
                    Integer val1 = obj1.getValue();
                    Integer val2 = obj2.getValue();
                    // DUPLICATE VALUE CASE
                    // If the values are equals, we can't return 0 because the 2 entries would be considered
                    // as equals and one of them would be deleted (because we use a set, no duplicate, remember!)
                    int compareValues = val1.compareTo(val2);
                    if ( compareValues == 0 ) {
                        String key1 = obj1.getKey();
                        String key2 = obj2.getKey();
                        int compareKeys = key1.compareTo(key2);
                        if ( compareKeys == 0 ) {
                            // what you return here will tell us if you keep REAL KEY-VALUE duplicates in your set
                            // if you want to, do whatever you want but do not return 0 (but don't break the comparator contract!)
                            return 0;
                        }
                        return compareKeys;
                    }
                    return compareValues;
                }
            }
    );
    set.addAll(mapToSortByValue.entrySet());


    // OK NOW OUR SET IS SORTED COOL!!!!

    // And there's nothing more to do: the entries are sorted by value!
    for ( Map.Entry<String,Integer> entry : set ) {
        System.out.println("Set entries:" + entry.getKey() +" ->" + entry.getValue());
    }




    // But if you add them to an hashmap
    Map<String,Integer> myMap = new HashMap<String,Integer>();
    // When iterating over the set the order is still good in the println...
    for ( Map.Entry<String,Integer> entry : set ) {
        System.out.println("Added to result map entries:" + entry.getKey() +"" + entry.getValue());
        myMap.put(entry.getKey(), entry.getValue());
    }

    // But once they are in the hashmap, the order is not kept!
    for ( Integer value : myMap.values() ) {
        System.out.println("Result map values:" + value);
    }
    // Also this way doesn't work:
    // Logic because the entryset is a hashset for hashmaps and not a treeset
    // (and even if it was a treeset, it would be on the keys only)
    for ( Map.Entry<String,Integer> entry : myMap.entrySet() ) {
        System.out.println("Result map entries:" + entry.getKey() +" ->" + entry.getValue());
    }


    // CONCLUSION:
    // If you want to iterate on a map ordered by value, you need to remember:
    // 1) Maps are only sorted by keys, so you can't sort them directly by value
    // 2) So you simply CAN'T return a map to a sortMapByValue function
    // 3) You can't reverse the keys and the values because you have duplicate values
    //    This also means you can't neither use Guava/Commons bidirectionnal treemaps or stuff like that

    // SOLUTIONS
    // So you can:
    // 1) only sort the values which is easy, but you loose the key/value link (since you have duplicate values)
    // 2) sort the map entries, but don't forget to handle the duplicate value case (like i did)
    // 3) if you really need to return a map, use a LinkedHashMap which keep the insertion order

    执行官:http://www.ideone.com/dq3lu

    输出:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    Set entries: E -> -1
    Set entries: B -> 1
    Set entries: A -> 3
    Set entries: C -> 3
    Set entries: D -> 5
    Set entries: H -> 15
    Set entries: G -> 79
    Set entries: F -> 1000
    Added to result map entries: E -1
    Added to result map entries: B 1
    Added to result map entries: A 3
    Added to result map entries: C 3
    Added to result map entries: D 5
    Added to result map entries: H 15
    Added to result map entries: G 79
    Added to result map entries: F 1000
    Result map values: 5
    Result map values: -1
    Result map values: 1000
    Result map values: 79
    Result map values: 3
    Result map values: 1
    Result map values: 3
    Result map values: 15
    Result map entries: D -> 5
    Result map entries: E -> -1
    Result map entries: F -> 1000
    Result map entries: G -> 79
    Result map entries: A -> 3
    Result map entries: B -> 1
    Result map entries: C -> 3
    Result map entries: H -> 15

    希望它能帮助一些人


    "输入。

    与Java的到来,我们可以使用数据流的操作在很容易/ succinct的方式。你可以使用两个黑色的流图和创造城市价值的一项,这一linkedhashmap preserves 25阶迭代法。

    如:

    1
    2
    3
    LinkedHashMap sortedByValueMap = map.entrySet().stream()
                    .sorted(comparing(Entry<Key,Value>::getValue).thenComparing(Entry::getKey))     //first sorting by Value, then sorting by Key(entries with same value)
                    .collect(LinkedHashMap::new,(map,entry) -> map.put(entry.getKey(),entry.getValue()),LinkedHashMap::putAll);

    逆向采购,replace:

    1
    comparing(Entry<Key,Value>::getValue).thenComparing(Entry::getKey)

    1
    comparing(Entry<Key,Value>::getValue).thenComparing(Entry::getKey).reversed()


    一些简单的更改,以便对具有重复值的已排序映射进行更改。在比较方法(类ValueComparator)中,当值相等时,不返回0,而是返回比较两个键的结果。键在映射中是不同的,因此可以成功地保留重复的值(按键排序)。所以上面的例子可以这样修改:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
        public int compare(Object a, Object b) {

            if((Double)base.get(a) < (Double)base.get(b)) {
              return 1;
            } else if((Double)base.get(a) == (Double)base.get(b)) {
              return ((String)a).compareTo((String)b);
            } else {
              return -1;
            }
          }
        }

    您可以尝试瓜娃的多重映射:

    1
    2
    3
    TreeMap<Integer, Collection<String>> sortedMap = new TreeMap<>(
            Multimaps.invertFrom(Multimaps.forMap(originalMap),
            ArrayListMultimap.<Integer, String>create()).asMap());

    结果,您得到了一个从原始值到对应于它们的键集合的映射。即使同一个值有多个键,也可以使用此方法。


    我已经合并了user157196和carter page的解决方案:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    class MapUtil {

        public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue( Map<K, V> map ){
            ValueComparator<K,V> bvc =  new ValueComparator<K,V>(map);
            TreeMap<K,V> sorted_map = new TreeMap<K,V>(bvc);
            sorted_map.putAll(map);
            return sorted_map;
        }

    }

    class ValueComparator<K, V extends Comparable<? super V>> implements Comparator<K> {

        Map<K, V> base;
        public ValueComparator(Map<K, V> base) {
            this.base = base;
        }

        public int compare(K a, K b) {
            int result = (base.get(a).compareTo(base.get(b)));
            if (result == 0) result=1;
            // returning 0 would merge keys
            return result;
        }
    }

    如果您有重复的密钥,并且只有一小部分数据(<1000),并且您的代码不是性能关键的,那么您可以执行以下操作:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    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语句中将>更改为a<即可。

    不是最快的排序,而是在没有任何附加依赖项的情况下执行作业。


    下面是Java 8与AbacusUtil的代码

    1
    2
    3
    4
    5
    Map<String, Integer> map = N.asMap("a", 2,"b", 3,"c", 1,"d", 2);
    Map<String, Integer> sortedMap = Stream.of(map.entrySet()).sorted(Map.Entry.comparingByValue()).toMap(e -> e.getKey(), e -> e.getValue(),
        LinkedHashMap::new);
    N.println(sortedMap);
    // output: {c=1, a=2, d=2, b=3}

    声明:我是AbacusUtil的开发者。


    This method will just serve the purpose. (the 'setback' is that the Values must implement the java.util.Comparable interface)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
      /**

     * Sort a map according to values.

     * @param <K> the key of the map.
     * @param <V> the value to sort according to.
     * @param mapToSort the map to sort.

     * @return a map sorted on the values.

     */

    public static <K, V extends Comparable< ? super V>> Map<K, V>
    sortMapByValues(final Map <K, V> mapToSort)
    {
        List<Map.Entry<K, V>> entries =
            new ArrayList<Map.Entry<K, V>>(mapToSort.size());  

        entries.addAll(mapToSort.entrySet());

        Collections.sort(entries,
                         new Comparator<Map.Entry<K, V>>()
        {
            @Override
            public int compare(
                   final Map.Entry<K, V> entry1,
                   final Map.Entry<K, V> entry2)
            {
                return entry1.getValue().compareTo(entry2.getValue());
            }
        });      

        Map<K, V> sortedMap = new LinkedHashMap<K, V>();      

        for (Map.Entry<K, V> entry : entries)
        {
            sortedMap.put(entry.getKey(), entry.getValue());

        }      

        return sortedMap;

    }

    http://javawithswaranga.blogspot.com/2011/06/generic-method-to-sort-hashmap.html


    当我面临with this,我只是创建list on the Side。如果你把他们在一起在执行自定义地图,它会有一个好的感觉到它。你可以使用一些像the following the sort only when,表演需要。(注:这真的还没有测试,但它compiles…愚蠢的小错误,会在有好的地方)P></

    (如果你想要它两类模式键和值,有treemap extend the class定义访问器方法,不要茶,有茶和被呼叫super.xxxxx instead of图_ .xxxx)P></

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    package com.javadude.sample;

    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.Collections;
    import java.util.Comparator;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.Set;

    public class SortedValueHashMap<K, V> implements Map<K, V> {
        private Map<K, V> map_ = new HashMap<K, V>();
        private List<V> valueList_ = new ArrayList<V>();
        private boolean needsSort_ = false;
        private Comparator<V> comparator_;

        public SortedValueHashMap() {
        }
        public SortedValueHashMap(List<V> valueList) {
            valueList_ = valueList;
        }

        public List<V> sortedValues() {
            if (needsSort_) {
                needsSort_ = false;
                Collections.sort(valueList_, comparator_);
            }
            return valueList_;
        }

        // mutators
        public void clear() {
            map_.clear();
            valueList_.clear();
            needsSort_ = false;
        }

        public V put(K key, V value) {
            valueList_.add(value);
            needsSort_ = true;
            return map_.put(key, value);
        }

        public void putAll(Map<? extends K, ? extends V> m) {
            map_.putAll(m);
            valueList_.addAll(m.values());
            needsSort_ = true;
        }

        public V remove(Object key) {
            V value = map_.remove(key);
            valueList_.remove(value);
            return value;
        }

        // accessors
        public boolean containsKey(Object key)           { return map_.containsKey(key); }
        public boolean containsValue(Object value)       { return map_.containsValue(value); }
        public Set<java.util.Map.Entry<K, V>> entrySet() { return map_.entrySet(); }
        public boolean equals(Object o)                  { return map_.equals(o); }
        public V get(Object key)                         { return map_.get(key); }
        public int hashCode()                            { return map_.hashCode(); }
        public boolean isEmpty()                         { return map_.isEmpty(); }
        public Set<K> keySet()                           { return map_.keySet(); }
        public int size()                                { return map_.size(); }
        public Collection<V> values()                    { return map_.values(); }
    }


    《simplest蛮力的方法sortHashMapHashMap:你只是copypaste和使用这样的信息:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    public class Test  {
        public static void main(String[] args)  {
            HashMap<String, Long> hashMap = new HashMap<>();
            hashMap.put("Cat", (long) 4);
            hashMap.put("Human", (long) 2);
            hashMap.put("Dog", (long) 4);
            hashMap.put("Fish", (long) 0);
            hashMap.put("Tree", (long) 1);
            hashMap.put("Three-legged-human", (long) 3);
            hashMap.put("Monkey", (long) 2);

            System.out.println(hashMap);  //{Human=2, Cat=4, Three-legged-human=3, Monkey=2, Fish=0, Tree=1, Dog=4}
            System.out.println(sortHashMap(hashMap));  //{Cat=4, Dog=4, Three-legged-human=3, Human=2, Monkey=2, Tree=1, Fish=0}
        }

        public LinkedHashMap<String, Long> sortHashMap(HashMap<String, Long> unsortedMap)  {
            LinkedHashMap<String, Long> result = new LinkedHashMap<>();

            //add String keys to an array: the array would get sorted, based on those keys' values
            ArrayList<String> sortedKeys = new ArrayList<>();
            for (String key: unsortedMap.keySet())  {
                sortedKeys.add(key);
            }

            //sort the ArrayList<String> of keys    
            for (int i=0; i<unsortedMap.size(); i++)  {
                for (int j=1; j<sortedKeys.size(); j++)  {
                    if (unsortedMap.get(sortedKeys.get(j)) > unsortedMap.get(sortedKeys.get(j-1))) {
                        String temp = sortedKeys.get(j);
                        sortedKeys.set(j, sortedKeys.get(j-1));
                        sortedKeys.set(j-1, temp);
                    }
                }
            }

            // construct the result Map
            for (String key: sortedKeys)  {
                result.put(key, unsortedMap.get(key));
            }

            return result;
        }
    }

    在rewrote devinmoore的排序方法,performs A市地图,它的价值没有使用迭代器:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    public static Map<K, V> sortMapByValue(Map<K, V> inputMap) {

        Set<Entry<K, V>> set = inputMap.entrySet();
        List<Entry<K, V>> list = new ArrayList<Entry<K, V>>(set);

        Collections.sort(list, new Comparator<Map.Entry<K, V>>()
        {
            @Override
            public int compare(Entry<K, V> o1, Entry<K, V> o2) {
                return (o1.getValue()).compareTo( o2.getValue() );  //Ascending order
            }
        } );

        Map<K, V> sortedMap = new LinkedHashMap<>();

        for(Map.Entry<K, V> entry : list){
            sortedMap.put(entry.getKey(), entry.getValue());
        }

        return sortedMap;
    }

    这是我们用Note:LinkedHashMap作为输出的地图,因为我们已经分离的城市的战略价值,现在我们应该为我们的大战略地图的输出与秩序插Key values。所以如果你使用例如TreeMap输出为你的地图,你的地图,将分离的城市地图的钥匙了!

    这是主要的方法:

    1
    2
    3
    4
    5
    6
    7
    8
    public static void main(String[] args) {
        Map<String, String> map = new HashMap<>();
        map.put("3","three");
        map.put("1","one");
        map.put("5","five");
        System.out.println("Input Map:" + map);
        System.out.println("Sorted Map:" + sortMapByValue(map));
    }

    终于,这是输出:

    1
    2
    Input Map:{1=one, 3=three, 5=five}
    Sorted Map:{5=five, 1=one, 3=three}

    如果有一Map对于大学有一个数据结构,inherently品种的市值没有触发任何品种具有两个或两个方法没有一通的效用,那么下面的解决方案可能是适用的:

    (1)(org.drools.chance.core.util.valuesortedmap JBoss项目)maintains一双internally查找地图和一个值为维持的分离。此前的两个类似的全新添加的答案,但也许它的abstraction和encapsulation方(包括复制机制),使得它更安全的使用从外面。

    (2)http:/ / / / techblog.molindo.at 2008年11月java-map-sorted-by-value.html avoids维持而不是常见的二维地图和/ extends从普通的linkedmap Apache。博客(笔者注:as all the code here is in the public domain):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    // required to access LinkEntry.before and LinkEntry.after
    package org.apache.commons.collections.map;

    // SNIP: imports

    /**
    * map implementation based on LinkedMap that maintains a sorted list of
    * values for iteration
    */

    public class ValueSortedHashMap extends LinkedMap {
        private final boolean _asc;

        // don't use super()!
        public ValueSortedHashMap(final boolean asc) {
            super(DEFAULT_CAPACITY);
            _asc = asc;
        }

        // SNIP: some more constructors with initial capacity and the like

        protected void addEntry(final HashEntry entry, final int hashIndex) {
            final LinkEntry link = (LinkEntry) entry;
            insertSorted(link);
            data[hashIndex] = entry;
        }

        protected void updateEntry(final HashEntry entry, final Object newValue) {
            entry.setValue(newValue);
            final LinkEntry link = (LinkEntry) entry;
            link.before.after = link.after;
            link.after.before = link.before;
            link.after = link.before = null;
            insertSorted(link);
        }

        private void insertSorted(final LinkEntry link) {
            LinkEntry cur = header;
            // iterate whole list, could (should?) be replaced with quicksearch
            // start at end to optimize speed for in-order insertions
            while ((cur = cur.before) != header & amp; & amp; !insertAfter(cur, link)) {}
            link.after = cur.after;
            link.before = cur;
            cur.after.before = link;
            cur.after = link;
        }

        protected boolean insertAfter(final LinkEntry cur, final LinkEntry link) {
            if (_asc) {
                return ((Comparable) cur.getValue())
                .compareTo((V) link.getValue()) & lt; = 0;
            } else {
                return ((Comparable) cur.getValue())
                .compareTo((V) link.getValue()) & gt; = 0;
            }
        }

        public boolean isAscending() {
            return _asc;
        }
    }

    (3)写一个自定义Map或extends从LinkedHashMap只读,将黑色的(例如,在enumeration values()keyset()AA,entryset())的需要。《内蒙古实施/冰abstracted行为从一个使用这两个类,但它出现这类客户是永远的价值,为enumeration分离要求的时候。本课程希望会发生3次,如果mostly全put作战已经completed enumerations之前。adopts排序方法在原有的一些回答这两个问题。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    public class SortByValueMap<K, V> implements Map<K, V> {

        private boolean isSortingNeeded = false;

        private final Map<K, V> map = new LinkedHashMap<>();

        @Override
        public V put(K key, V value) {
            isSortingNeeded = true;
            return map.put(key, value);
        }

        @Override
        public void putAll(Map<? extends K, ? extends V> map) {
            isSortingNeeded = true;
            map.putAll(map);
        }

        @Override
        public Set<K> keySet() {
            sort();
            return map.keySet();
        }

        @Override
        public Set<Entry<K, V>> entrySet() {
            sort();
            return map.entrySet();
        }

        @Override
        public Collection<V> values() {
            sort();
            return map.values();
        }

        private void sort() {
            if (!isSortingNeeded) {
                return;
            }

            List<Entry<K, V>> list = new ArrayList<>(size());

            for (Iterator<Map.Entry<K, V>> it = map.entrySet().iterator(); it.hasNext();) {
                Map.Entry<K, V> entry = it.next();
                list.add(entry);
                it.remove();
            }

            Collections.sort(list);

            for (Entry<K, V> entry : list) {
                map.put(entry.getKey(), entry.getValue());
            }

            isSortingNeeded = false;
        }

        @Override
        public String toString() {
            sort();
            return map.toString();
        }
    }

    (4)immutablemap.builder.orderentriesbyvalue石榴者(对照valuecomparator)尽管《resulting图将immutable:

    Configures this Builder to order entries by value according to the
    specified comparator.

    The sort order is stable, that is, if two entries have values that
    compare as equivalent, the entry that was inserted first will be first
    in the built map's iteration order.


    我的解决方案是使用大多数给定API的一种非常简单的方法。我们使用map的特性通过entryset()方法将其内容导出为集合。我们现在有一个包含map.entry对象的集合。

    好的,一个集合不携带一个命令,但是我们可以把内容放入一个数组列表。它现在有一个随机顺序,但我们无论如何都会对它进行排序。

    由于arraylist是一个集合,所以我们现在使用collections.sort()方法来混乱排序。因为map.entry对象没有实现我们需要的比较,所以我们提供了一个定制的比较器。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    public static void main(String[] args) {
        HashMap<String, String> map = new HashMap<>();
        map.put("Z","E");
        map.put("G","A");
        map.put("D","C");
        map.put("E", null);
        map.put("O","C");
        map.put("L","D");
        map.put("Q","B");
        map.put("A","F");
        map.put(null,"X");
        MapEntryComparator mapEntryComparator = new MapEntryComparator();

        List<Entry<String,String>> entryList = new ArrayList<>(map.entrySet());
        Collections.sort(entryList, mapEntryComparator);

        for (Entry<String, String> entry : entryList) {
            System.out.println(entry.getKey() +" :" + entry.getValue());
        }

    }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    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
    "
    );
        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);
        }  
    }

    输出

    1
    2
    3
    4
    5
    6
    7
    8
    //sort by values

    3 arun singh
    1 bandagi singh
    28 jakarta singh
    2 panipat singh
    6 vikram singh
    5 vinay singh


    for the keys的sorting河畔发现更好的解决方案,在与treemap(to get a solution会尝试基于价值sorting太好):P></

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    public static void main(String[] args) {
        Map<String, String> unsorted = new HashMap<String, String>();
        unsorted.put("Cde","Cde_Value");
        unsorted.put("Abc","Abc_Value");
        unsorted.put("Bcd","Bcd_Value");

        Comparator<String> comparer = new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o1.compareTo(o2);
            }};

        Map<String, String> sorted = new TreeMap<String, String>(comparer);
        sorted.putAll(unsorted);
        System.out.println(sorted);
    }

    输出:我会好的P></

    _ = { ABC ABC BCD BCD _ =价值,价值,价值_ CDE CDE=}P></


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    public class SortedMapExample {

        public static void main(String[] args) {
            Map<String, String> map = new HashMap<String, String>();

            map.put("Cde","C");
            map.put("Abc","A");
            map.put("Cbc","Z");
            map.put("Dbc","D");
            map.put("Bcd","B");
            map.put("sfd","Bqw");
            map.put("DDD","Bas");
            map.put("BGG","Basd");

            System.out.println(sort(map, new Comparator<String>() {
                @Override
                public int compare(String o1, String o2) {
                        return o1.compareTo(o2);
                }}));
        }

        @SuppressWarnings("unchecked")
        public static <K, V> Map<K,V> sort(Map<K, V> in, Comparator<? super V> compare) {
            Map<K, V> result = new LinkedHashMap<K, V>();
            V[] array = (V[])in.values().toArray();
            for(int i=0;i<array.length;i++)
            {

            }
            Arrays.sort(array, compare);
            for (V item : array) {
                K key= (K) getKey(in, item);
                result.put(key, item);
            }
            return result;
        }

        public static <K, V>  Object getKey(Map<K, V> in,V value)
        {
           Set<K> key= in.keySet();
           Iterator<K> keyIterator=key.iterator();
           while (keyIterator.hasNext()) {
               K valueObject = (K) keyIterator.next();
               if(in.get(valueObject).equals(value))
               {
                       return valueObject;
               }
           }
           return null;
       }

    }

    //请在这里试试。我正在修改值排序的代码。


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
        static <K extends Comparable<? super K>, V extends Comparable<? super V>>
        Map sortByValueInDescendingOrder(final Map<K, V> map) {
            Map re = new TreeMap(new Comparator<K>() {
                @Override
                public int compare(K o1, K o2) {
                    if (map.get(o1) == null || map.get(o2) == null) {
                        return -o1.compareTo(o2);
                    }
                    int result = -map.get(o1).compareTo(map.get(o2));
                    if (result != 0) {
                        return result;
                    }
                    return -o1.compareTo(o2);
                }
            });
            re.putAll(map);
            return re;
        }
        @Test(timeout = 3000l, expected = Test.None.class)
        public void testSortByValueInDescendingOrder() {
            char[] arr ="googler".toCharArray();
            Map<Character, Integer> charToTimes = new HashMap();
            for (int i = 0; i < arr.length; i++) {
                Integer times = charToTimes.get(arr[i]);
                charToTimes.put(arr[i], times == null ? 1 : times + 1);
            }
            Map sortedByTimes = sortByValueInDescendingOrder(charToTimes);
            Assert.assertEquals(charToTimes.toString(),"{g=2, e=1, r=1, o=2, l=1}");
            Assert.assertEquals(sortedByTimes.toString(),"{o=2, g=2, r=1, l=1, e=1}");
            Assert.assertEquals(sortedByTimes.containsKey('a'), false);
            Assert.assertEquals(sortedByTimes.get('a'), null);
            Assert.assertEquals(sortedByTimes.get('g'), 2);
            Assert.assertEquals(sortedByTimes.equals(charToTimes), true);
        }

    如果没有任何大于地图大小的值,可以使用数组,这应该是最快的方法:

    1
    2
    3
    4
    5
    6
    7
    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);
    }


    好吧,这版本与新的对象和作品两图的种类和二值iterations在线。好希望,尽管performs the must be the map:两次looped entriesP></

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    public static void main(String[] args) {
        Map<String, String> unsorted = new HashMap<String, String>();
        unsorted.put("Cde","Cde_Value");
        unsorted.put("Abc","Abc_Value");
        unsorted.put("Bcd","Bcd_Value");

        Comparator<String> comparer = new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o1.compareTo(o2);
            }};

        System.out.println(sortByValue(unsorted, comparer));

    }

    public static <K, V> Map<K,V> sortByValue(Map<K, V> in, Comparator<? super V> compare) {
        Map<V, K> swapped = new TreeMap<V, K>(compare);
        for(Entry<K,V> entry: in.entrySet()) {
            if (entry.getValue() != null) {
                swapped.put(entry.getValue(), entry.getKey());
            }
        }
        LinkedHashMap<K, V> result = new LinkedHashMap<K, V>();
        for(Entry<V,K> entry: swapped.entrySet()) {
            if (entry.getValue() != null) {
                result.put(entry.getValue(), entry.getKey());
            }
        }
        return result;
    }

    解决方案:在一uses treemap comparator超时空键的种类和布尔值。第一,茶叶功能性treemap序from the is used to the next the sort值河畔,is used to create a map类linkedhashmap as a result of that has the same retains阶值。P></

    greetz,ghadP></


    我们只是这样对地图排序

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
                Map<String, String> unsortedMap = new HashMap<String, String>();

        unsortedMap.put("E","E Val");
        unsortedMap.put("F","F Val");
        unsortedMap.put("H","H Val");
        unsortedMap.put("B","B Val");
        unsortedMap.put("C","C Val");
        unsortedMap.put("A","A Val");
        unsortedMap.put("G","G Val");
        unsortedMap.put("D","D Val");

        Map<String, String> sortedMap = new TreeMap<String, String>(unsortedMap);

        System.out.println("
    After sorting.."
    );
        for (Map.Entry <String, String> mapEntry : sortedMap.entrySet()) {
            System.out.println(mapEntry.getKey() +" \t" + mapEntry.getValue());


    最好的方法是将hashmap转换为treemap。treemap单独排序键。如果要对值进行排序,则可以使用键切换值(如果值不重复)。


    因为地图无序为了排序,我们可以执行以下操作

    1
    Map<String, String> map= new TreeMap<String, String>(unsortMap);

    您应该注意,与散列映射不同,树映射保证其元素将按升序键顺序排序。


    如果你的地图(例如,字符串值),实施"订单comparable this should workP></

    1
    2
    3
    4
    Map<Object, String> map = new HashMap<Object, String>();
    // Populate the Map
    List<String> mapValues = new ArrayList<String>(map.values());
    Collections.sort(mapValues);

    图themselves if the values不实施"订单comparable,but You have an instance of that can comparable Sort them with this,replace the last:在线P></

    1
    Collections.sort(mapValues, comparable);


    使用java.util.treemap。P></

    "the map is of the自然序类根据其提供的钥匙,在AT模式或comparator图创作在线时间,which is used depending构造函数。"P></