IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    java 中对 map根据key或者value进行排序的测试

    asuncool@gmail.com(yihaomen)发表于 2016-08-16 23:13:42
    love 0
    以前在java中对map进行排序通常会自己单独定义一个方法出来处理,特别是根据 value  进行排序更是麻烦一些,但在java 8 总似乎可以用简单一点的方法处理了,直接用测试代码。
    程序代码 程序代码

    import java.util.HashMap;
    import java.util.LinkedHashMap;
    import java.util.Map;

    public class SortByKeyExample {

        public static void main(String[] argv) {

            Map<String, Integer> unsortMap = new HashMap<>();
            unsortMap.put("z", 10);
            unsortMap.put("b", 5);
            unsortMap.put("a", 6);
            unsortMap.put("c", 20);
            unsortMap.put("d", 1);
            unsortMap.put("e", 7);
            unsortMap.put("y", 8);
            unsortMap.put("n", 99);
            unsortMap.put("j", 50);
            unsortMap.put("m", 2);
            unsortMap.put("f", 9);

            System.out.println("Original...");
            System.out.println(unsortMap);

            Map<String, Integer> result = new LinkedHashMap<>();

            //sort by key, a,b,c..., and put it into the "result" map
            unsortMap.entrySet().stream()
                    .sorted(Map.Entry.<String, Integer>comparingByKey())
                    .forEachOrdered(x -> result.put(x.getKey(), x.getValue()));

            System.out.println("Sorted...");
            System.out.println(result);

        }

    }

    结果如下:
    程序代码 程序代码

    original...
    {a=6, b=5, c=20, d=1, e=7, f=9, y=8, z=10, j=50, m=2, n=99}

    Sorted...
    {a=6, b=5, c=20, d=1, e=7, f=9, j=50, m=2, n=99, y=8, z=10}



    当然上面是根据key进行排序的。 但如果根据value进行排序呢, 如何处理.

    程序代码 程序代码

    import java.util.HashMap;
    import java.util.LinkedHashMap;
    import java.util.Map;

    public class SortByValueExample {

        public static void main(String[] argv) {

            Map<String, Integer> unsortMap = new HashMap<>();
            unsortMap.put("z", 10);
            unsortMap.put("b", 5);
            unsortMap.put("a", 6);
            unsortMap.put("c", 20);
            unsortMap.put("d", 1);
            unsortMap.put("e", 7);
            unsortMap.put("y", 8);
            unsortMap.put("n", 99);
            unsortMap.put("j", 50);
            unsortMap.put("m", 2);
            unsortMap.put("f", 9);

            System.out.println("Original...");
            System.out.println(unsortMap);

            Map<String, Integer> result = new LinkedHashMap<>();

            //sort by value, and reserve, 10,9,8,7,6...
            unsortMap.entrySet().stream()
                    .sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
                    .forEachOrdered(x -> result.put(x.getKey(), x.getValue()));

            System.out.println("Sorted...");
            System.out.println(result);

        }

    }

    结果如下:
    程序代码 程序代码

    original...
    {a=6, b=5, c=20, d=1, e=7, f=9, y=8, z=10, j=50, m=2, n=99}

    Sorted...
    {n=99, j=50, c=20, z=10, f=9, y=8, e=7, a=6, b=5, m=2, d=1}


    再继续,如果要写一个通用的方法呢,按下面的处理吧:
    程序代码 程序代码

    import java.util.HashMap;
    import java.util.LinkedHashMap;
    import java.util.Map;
    import java.util.stream.Stream;

    public class SortByGenericExample {

        public static void main(String[] argv) {

            Map<String, Integer> unsortMap = new HashMap<>();
            unsortMap.put("z", 10);
            unsortMap.put("b", 5);
            unsortMap.put("a", 6);
            unsortMap.put("c", 20);
            unsortMap.put("d", 1);
            unsortMap.put("e", 7);
            unsortMap.put("y", 8);
            unsortMap.put("n", 99);
            unsortMap.put("j", 50);
            unsortMap.put("m", 2);
            unsortMap.put("f", 9);

            System.out.println("Original...");
            System.out.println(unsortMap);

            System.out.println("Sort By Key...");
            Map<String, Integer> resultKey = compareByKey(unsortMap);
            System.out.println(resultKey);

            System.out.println("Sort By Value...");
            Map<String, Integer> resultValue = compareByValue(unsortMap);
            System.out.println(resultValue);
        }

        //Reference from java.util.Map source code, try dig inside, many generic examples.
        public static <K, V extends Comparable<? super V>> Map<K, V> compareByValue(Map<K, V> map) {

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

            Stream<Map.Entry<K, V>> mapInStream = map.entrySet().stream();

            mapInStream.sorted(Map.Entry.comparingByValue())
                    .forEachOrdered(x -> result.put(x.getKey(), x.getValue()));

            return result;

        }

        public static <K extends Comparable<? super K>, V> Map<K, V> compareByKey(Map<K, V> map) {

            Map<K, V> result = new LinkedHashMap<>();
            Stream<Map.Entry<K, V>> mapInStream = map.entrySet().stream();

            mapInStream.sorted(Map.Entry.comparingByKey())
                    .forEachOrdered(x -> result.put(x.getKey(), x.getValue()));

            return result;

        }

    }


    结果如下:
    程序代码 程序代码

    original...
    {a=6, b=5, c=20, d=1, e=7, f=9, y=8, z=10, j=50, m=2, n=99}

    Sort By Key...
    {a=6, b=5, c=20, d=1, e=7, f=9, j=50, m=2, n=99, y=8, z=10}

    Sort By Value...
    {d=1, m=2, b=5, a=6, e=7, y=8, f=9, z=10, c=20, j=50, n=99}


    以上是java8 中才使用的,如果不是用的java8 怎么办,下面附录中有方法,也就是以前的传统方法:
    根据key排序,利用 TreeMap:
    程序代码 程序代码

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

    public class SortByKeyExample1 {

        public static void main(String[] args) {

            Map<String, String> unsortMap = new HashMap<String, String>();
            unsortMap.put("Z", "z");
            unsortMap.put("B", "b");
            unsortMap.put("A", "a");
            unsortMap.put("C", "c");
            unsortMap.put("D", "d");
            unsortMap.put("E", "e");
            unsortMap.put("Y", "y");
            unsortMap.put("N", "n");
            unsortMap.put("J", "j");
            unsortMap.put("M", "m");
            unsortMap.put("F", "f");

            System.out.println("Unsort Map......");
            printMap(unsortMap);

            System.out.println("\nSorted Map......By Key");
            Map<String, String> treeMap = new TreeMap<String, String>(unsortMap);
            printMap(treeMap);

        }

        //pretty print a map
        public static <K, V> void printMap(Map<K, V> map) {
            for (Map.Entry<K, V> entry : map.entrySet()) {
                System.out.println("Key : " + entry.getKey()
                    + " Value : " + entry.getValue());
            }
        }

    }


    如果是根据value进行排序呢, 将map转为 List<Map>, 然后 对List<Map> 利用 Comparator 排序,把结果放到一个LinkedHashMap 中去, 也就是这个过程:
    Map ---> List<Map> ---> Collections.sort() --> List<Map> (Sorted) ---> LinkedHashMap

    程序代码 程序代码

    import java.util.*;

    public class SortByValueExample1 {

        public static void main(String[] args) {

            Map<String, Integer> unsortMap = new HashMap<String, Integer>();
            unsortMap.put("z", 10);
            unsortMap.put("b", 5);
            unsortMap.put("a", 6);
            unsortMap.put("c", 20);
            unsortMap.put("d", 1);
            unsortMap.put("e", 7);
            unsortMap.put("y", 8);
            unsortMap.put("n", 99);
            unsortMap.put("j", 50);
            unsortMap.put("m", 2);
            unsortMap.put("f", 9);

            System.out.println("Unsort Map......");
            printMap(unsortMap);

            System.out.println("\nSorted Map......By Value");
            Map<String, Integer> sortedMap = sortByValue(unsortMap);
            printMap(sortedMap);

        }

        private static Map<String, Integer> sortByValue(Map<String, Integer> unsortMap) {

            // 1. Convert Map to List of Map
            List<Map.Entry<String, Integer>> list =
                    new LinkedList<Map.Entry<String, Integer>>(unsortMap.entrySet());

            // 2. Sort list with Collections.sort(), provide a custom Comparator
            //    Try switch the o1 o2 position for a different order
            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());
                }
            });

            // 3. Loop the sorted list and put it into a new insertion order Map LinkedHashMap
            Map<String, Integer> sortedMap = new LinkedHashMap<String, Integer>();
            for (Map.Entry<String, Integer> entry : list) {
                sortedMap.put(entry.getKey(), entry.getValue());
            }

            /*
            //classic iterator example
            for (Iterator<Map.Entry<String, Integer>> it = list.iterator(); it.hasNext(); ) {
                Map.Entry<String, Integer> entry = it.next();
                sortedMap.put(entry.getKey(), entry.getValue());
            }*/


            return sortedMap;
        }

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

    }


    当然 sortByValue 也可以写成一个通用的方法:
    程序代码 程序代码

    public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> unsortMap) {

        List<Map.Entry<K, V>> list =
                new LinkedList<Map.Entry<K, V>>(unsortMap.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;

    }


沪ICP备19023445号-2号
友情链接