Java 如何根据值对树状图进行排序?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1448369/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 12:23:09  来源:igfitidea点击:

How to sort a treemap based on its values?

javatreemap

提问by Click Upvote

How can I sort a treemap using its values rather than the key?

如何使用值而不是键对树状图进行排序?

采纳答案by Zed

You cannot as the TreeMap's comparator is run against the keys only, e.g. see this constructor.

您不能因为 TreeMap 的比较器仅针对键运行,例如,请参阅此构造函数

Anyway, you can use multiple Collections, use the TreeMap (or rather HashMap) for looking up elements by keys, and have a SortedSet to iterate on the values.

无论如何,您可以使用多个集合,使用 TreeMap(或者更确切地说是 HashMap)通过键查找元素,并使用 SortedSet 来迭代这些值。

回答by starblue

Swap values and keys.

交换值和键。

More seriously, please provide some context what you want to achieve. Maybe it is enough to sort after other processing is finished.

更严重的是,请提供一些您想要实现的上下文。也许在其他处理完成后进行排序就足够了。

回答by Vincent Robert

You could try giving a Comparator that compare values instead of keys when you create the TreeMap.

您可以尝试在创建 TreeMap 时提供一个比较值而不是键的比较器。

    final TreeMap<Integer,String> tree = new TreeMap<Integer,String>();
    tree.put(1, "1");
    tree.put(2, "2");
    tree.put(3, "3");
    tree.put(4, "4");

    final TreeMap<Integer,String> treeSortedByValues = new TreeMap<Integer,String>(new Comparator<Integer>()
    {
        public int compare(Integer o1, Integer o2)
        {
            return tree.get(o1).compareTo(tree.get(o2));
        }
    });
    treeSortedByValues.putAll(tree);

    for ( Entry<Integer, String> e : treeSortedByValues.entrySet() )
    {
        System.out.println(e.getKey() + ": " + e.getValue());
    }

回答by skaffman

Apache Commons Collectionshas a TreeBidiMap:

Apache Commons Collections有一个TreeBidiMap

This class guarantees that the map will be in both ascending key order and ascending value order, sorted according to the natural order for the key's and value's classes.

此类保证映射将按升序键顺序和升序值顺序排列,根据键和值的类的自然顺序进行排序。

There's a Java5-generics port of it here.

有它的一个Java5的,仿制药口这里

回答by richs

Google Guava provides a TreeMultiMap.

谷歌番石榴提供了一个TreeMultiMap

You could also use two collections. What are you trying to accomplish? Can you explain your use cases?

您也可以使用两个集合。你想达到什么目的?你能解释一下你的用例吗?

回答by Anthony

Here is a solution:

这是一个解决方案:

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;
}

Note that the map is sorted from the highest value to the lowest.

请注意,地图是从最高值到最低值排序的。

回答by Rais Alam

Try below code it works fine for me. You can choose both ascending as well as descending order for sorting.

试试下面的代码,它对我来说很好用。您可以选择升序和降序进行排序。

package com.rais;

import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

public class SortMapByValue
{
    public static boolean ASC = true;
    public static boolean DESC = false;

    public static void main(String[] args)
    {

        // Creating dummy unsorted map
        Map<String, Integer> unsortMap = new HashMap<String, Integer>();
        unsortMap.put("B", 55);
        unsortMap.put("A", 80);
        unsortMap.put("D", 20);
        unsortMap.put("C", 70);

        System.out.println("Before sorting......");
        printMap(unsortMap);

        System.out.println("After sorting ascending order......");
        Map<String, Integer> sortedMapAsc = sortByComparator(unsortMap, ASC);
        printMap(sortedMapAsc);


        System.out.println("After sorting descindeng order......");
        Map<String, Integer> sortedMapDesc = sortByComparator(unsortMap, DESC);
        printMap(sortedMapDesc);

    }

    private static Map<String, Integer> sortByComparator(Map<String, Integer> unsortMap, final boolean order)
    {

        List<Entry<String, Integer>> list = new LinkedList<Entry<String, Integer>>(unsortMap.entrySet());

        // Sorting the list based on values
        Collections.sort(list, new Comparator<Entry<String, Integer>>()
        {
            public int compare(Entry<String, Integer> o1,
                    Entry<String, Integer> o2)
            {
                if (order)
                {
                    return o1.getValue().compareTo(o2.getValue());
                }
                else
                {
                    return o2.getValue().compareTo(o1.getValue());

                }
            }
        });

        // Maintaining insertion order with the help of LinkedList
        Map<String, Integer> sortedMap = new LinkedHashMap<String, Integer>();
        for (Entry<String, Integer> entry : list)
        {
            sortedMap.put(entry.getKey(), entry.getValue());
        }

        return sortedMap;
    }

    public static void printMap(Map<String, Integer> map)
    {
        for (Entry<String, Integer> entry : map.entrySet())
        {
            System.out.println("Key : " + entry.getKey() + " Value : "+ entry.getValue());
        }
    }
}

回答by Ritwik Jain

That's I have done this..

那是我做了这个..

package Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;

class MyComparator implements Comparator<Object> {

    public int compare(Object o1, Object o2) {
        return (((Integer) o2).compareTo((Integer) o1));
    }
}

class MyComparator1 implements Comparator<Object> {
    Map<Integer, String> map;

    public MyComparator1(Map<Integer, String> m) {
        this.map = m;
    }

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

public class Map1 {
    public static void main(String[] args) {
        Map<Integer, String> hmap = new HashMap<Integer, String>();
        hmap.put(5, "Ashok");
        hmap.put(21, "Bhanu");
        hmap.put(7, "chaman");
        hmap.put(28, "dheeraj");
        hmap.put(761, "edison");
        hmap.put(1, "frank");
        hmap.put(-6, "gopal");
        hmap.put(78, "hari");
        System.out.println("Hash Map:" + hmap);
        Map<Integer, String> tmap = new TreeMap<>(hmap);
        System.out.println("Tree Map:" + tmap);
        MyComparator comp = new MyComparator();
        Map<Integer, String> itmap = new TreeMap<>(comp);
        itmap.putAll(hmap);
        System.out.println("Tree Map Inreverse order:" + itmap);
        Map<Integer, String> orderValuemap = new TreeMap<Integer, String>(new 
            MyComparator1(hmap));
            orderValuemap.putAll(hmap);
            orderValuemap.put(22,"hello");
        for(Entry<Integer, String> mp:orderValuemap.entrySet())
            System.out.println("Value : "+mp.getValue());
    }
}

回答by Iy 716

Try this. This sorts TreeMap values in ascending order, assuming that is how you want the values to be sorted.

尝试这个。这将按升序对 TreeMap 值进行排序,假设这是您希望对值进行排序的方式。

static <K, V> Map<K, V> sortByValues(Map<K, V> map) {
        List<?> list = new ArrayList(map.entrySet());

        // copy Map to List to use Comparator
        Collections.sort(list, new Comparator() {
            public int compare(Object o1, Object o2) {
                return ((Comparable) ((Map.Entry) o1).getValue()).compareTo(((Map.Entry) o2).getValue());
            }
        });

        // then copy List to LinkedHashMap as it preserves insertion order
        Map<K, V> result = new LinkedHashMap<K, V>();
        Iterator itr = list.iterator();
        while (itr.hasNext()) {
            Map.Entry<K, V> m = (Map.Entry<K, V>) itr.next();
            result.put(m.getKey(), m.getValue());
        }

        return result;
    }