Java集合(五五):Map 的排序问题

本文详细介绍如何使用Java对Map进行排序,包括根据Key、Value及Value长度的多种排序方法。不仅覆盖了TreeMap、HashMap等常见Map类型的应用,还介绍了如何利用Pair类、匿名内部类、lambda表达式等多种技巧实现灵活排序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

1、根据Key进行排序

2、根据value值排序

3、根据value的长度排序

3.1、用Pair配对

首先存储配对到集合中:

对集合进行排序

3.2、用TreeMap进行排序

3.3、HashMap转成list再排序


1、根据Key进行排序

Map的根据key排序需要用到TreeMap对象,因为它是默认按照升序进行输出的,可以使用比较器compareTo对它进行降序排序,Comparator可以对集合对象或者数组进行排序的比较器接口,实现该接口的public compare(T o1,To2)方法即可实现排序,该方法主要是根据第一个参数o1,小于、等于或者大于o2分别返回负整数、0或者正整数,若是按照升序可以直接省略比较器代码Map<String, String> treeMap = new TreeMap<String, String>();

           return 0;    // 只返回存储的第一个key的值,这里是{c=ddddd}
            }
        });
//        Map<String, String> treeMap = new TreeMap<String, String>();
        treeMap.put("c", "ccccc");
        treeMap.put("a", "aaaaa");
        treeMap.put("b", "bbbbb");
        treeMap.put("d", "ddddd");
        System.out.println(treeMap);
    }
}
{a=aaaaa, b=bbbbb, c=ccccc, d=ddddd}

2、根据value值排序

        利用List排序

        对value排序我们就需要借助于Collections的sort(List<T> list, Comparator<? super T> c)方法,该方法根据指定比较器产生的顺序对指定列表进行排序。但是有一个前提条件,那就是所有的元素都必须能够根据所提供的比较器来进行比较。

这种方法通用于key和value排序,只需将比较器中o1.getValue().compareTo(o2.getValue())的getValue()改为getKey()即可。

public class MapTest
{

    public static void main(String[] args) {
        Map map = new HashMap();
        map.put("设计与制作", "52");
        map.put("创作表现", "15");
        map.put("基本元素", "48");
        map.put("艺术作品", "55");

        //Set<Map.Entry<K, V>> entrySet();
        List<Map.Entry<String,String>> list = new ArrayList<>(map.entrySet());
        Collections.sort(list,new Comparator<Map.Entry<String,String>>(){
            @Override
            public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
                return o1.getValue().compareTo(o2.getValue());
            }
        });

        Map<String,String> mapNew = new LinkedHashMap<>();
        for (Map.Entry<String,String> entry:list){
            mapNew.put(entry.getKey(),entry.getValue());
        }
        System.out.println(mapNew);


    }
{创作表现=15, 基本元素=48, 设计与制作=52, 艺术作品=55}

3、根据value的长度排序

        需求:存储一个key为Integer,value为String的map,根据String长度对map从小到大排序

clipboard.png

结果:

clipboard.png

3.1、用Pair配对

        一开始用的是HashMap,但是后面发现HashMap是无序的,于是想把HashMap的一个键值对取出来,存到集合里,再对集合进行自定义排序,上网搜到有一个配对的类Pair,他有一个key和一个value属性,想到用来代替HashMap的一个键值对。

clipboard.png

用ArrayList代替HashMap,然后ArrayList中的元素为配对类,变相实现了一个键对应一个值的集合,并且能够排序

首先存储配对到集合中:

       ArrayList<Pair<Integer, String>> pairs = new ArrayList<>();
        Pair<Integer, String> pair;
        pair = new Pair<>(1, "abc");
        pairs.add(pair);
        pair = new Pair<>(2, "abcd");
        pairs.add(pair);
        pair = new Pair<>(3, "ab");
        pairs.add(pair);
        pair = new Pair<>(4, "abcde");
        pairs.add(pair);

对集合进行排序

调用ArrayList对象的sort方法进行排序,他需要Comparator接口,有三种实现方法:

内部类进行排序

public class Main {

    public static void main(String[] args) {
        ArrayList<Pair<Integer, String>> pairs = new ArrayList<>();
        Pair<Integer, String> pair;
        pair = new Pair<>(1, "abc");
        pairs.add(pair);
        pair = new Pair<>(2, "abcd");
        pairs.add(pair);
        pair = new Pair<>(3, "ab");
        pairs.add(pair);
        pair = new Pair<>(4, "abcde");
        pairs.add(pair);
        pairs.sort(new Main().new StringCmp());//建立Main内部类的一个实例对象
    }
    //实现比较接口的内部类
    public class StringCmp implements Comparator{
        @Override
        public int compare(Object o1, Object o2) {
            Pair<Integer, String> s1 = (Pair)o1;
            Pair<Integer, String> s2 = (Pair)o2;
            return new Integer(s1.getValue().length()).compareTo(s2.getValue().length());
        }
    }
}

匿名内部类进行排序

如果不需要复用这个排序的方法,单独为他写一个类太过浪费又不安全,可以使用匿名的内部类

public class Main {

    public static void main(String[] args) {
        ArrayList<Pair<Integer, String>> pairs = new ArrayList<>();
        Pair<Integer, String> pair;
        pair = new Pair<>(1, "abc");
        pairs.add(pair);
        pair = new Pair<>(2, "abcd");
        pairs.add(pair);
        pair = new Pair<>(3, "ab");
        pairs.add(pair);
        pair = new Pair<>(4, "abcde");
        pairs.add(pair);
        //使用匿名内部类
        pairs.sort(new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                Pair<Integer, String> s1 = (Pair)o1;
                Pair<Integer, String> s2 = (Pair)o2;
                return new Integer(s1.getValue().length()).compareTo(s2.getValue().length());
            }
        });

    }
}

lambda表达式

lambda表达式就是匿名内部类的简写版:

public class Main {

    public static void main(String[] args) {
        ArrayList<Pair<Integer, String>> pairs = new ArrayList<>();
        Pair<Integer, String> pair;
        pair = new Pair<>(1, "abc");
        pairs.add(pair);
        pair = new Pair<>(2, "abcd");
        pairs.add(pair);
        pair = new Pair<>(3, "ab");
        pairs.add(pair);
        pair = new Pair<>(4, "abcde");
        pairs.add(pair);
        pairs.sort((pair1, pair2)->{return new Integer(pair1.getValue().length()).compareTo(new Integer(pair2.getValue().length()));});
    }
}

3.2、用TreeMap进行排序

        Map有能够排序的实现类TreeMap,创建时传入Comparator的接口实现类,就能够实现存储是排序了:

public class MapTest{
    public static void main(String[] args) {

        TreeMap<String, Integer> treeMap = new TreeMap<String, Integer>((s1, s2)->{
            return new Integer(s1.length()).compareTo(new Integer(s2.length()));
        });

        treeMap.put("aec",1);
        treeMap.put("abcd",2);
        treeMap.put("ab",3);
        treeMap.put("abcde",4);
    }
}
        System.out.println(treeMap);//{ab=3, aec=1, abcd=2, abcde=4}

        因为TreeMap只能按照key进行排序,而我的要求是根据value的长度进行排序,所有在这里我把key和value的类型互换了,但这样之前可以通过int类型的编号找到String类型值,在更改之后,就不能通过标号找到值了。虽然有好处良多,但是不符合我的情况。

3.3、HashMap转成list再排序

        把HashMap转换为Set之后再转换成ArrayList再调用sort方法进行排序,达到根据value进行排序的效果:

public class Main {

    public static void main(String[] args) {
        HashMap<Integer, String> hashMap = new HashMap<>();
        hashMap.put(1, "aec");
        hashMap.put(2, "abcd");
        hashMap.put(3, "ab");
        hashMap.put(4, "abcde");
        ArrayList<Map.Entry<Integer, String>> arrayList = new ArrayList<>(hashMap.entrySet());
        arrayList.sort((entry1, entry2)->{
            return new Integer(entry1.getValue().length()).compareTo(new Integer(entry2.getValue().length()));
        });
    }
}

感觉这是第一种方法,加上一个HashMap得到的结果,这样可以从按照value进行排序(排序结果保存在arrayList中),也可以从key找到value(在HashMap中),但是存储内存却浪费了,多了一个list,不知道有没有直接根据value直接排序的map.

public class TestMapSort {

    public static void main(String[] args) {
        int i = new Integer(1).compareTo(3);
        System.out.println(i);//-1
        //Pair类在javafx.util 包中
        List<Pair<Integer,String>> pairs = Lists.newArrayListWithExpectedSize(1);
        Pair<Integer, String> pair;
        pair = new Pair<>(1,"abc");
        pairs.add(pair);
        pair = new Pair<>(2, "abcd");
        pairs.add(pair);
        pair = new Pair<>(3, "ab");
        pairs.add(pair);
        pair = new Pair<>(4, "abcde");
        pairs.add(pair);

        pairs.sort(new Comparator<Pair<Integer, String>>() {
            @Override
            public int compare(Pair<Integer, String> o1, Pair<Integer, String> o2) {
                if(o1.getValue().length() < o2.getValue().length()){
                    return -1;
                }else return 1;
            }
        });
        System.out.println(pairs);//[3=ab, 1=abc, 2=abcd, 4=abcde]

        pairs.sort(new ComparePairs());
        System.out.println(pairs);//[3=ab, 1=abc, 2=abcd, 4=abcde]

        pairs.sort(
                (p1,p2)->{
                    return new Integer(p1.getValue().length()).compareTo(p2.getValue().length());
                });
        System.out.println(pairs);//[3=ab, 1=abc, 2=abcd, 4=abcde]
        pairs.sort(
                (p1,p2)->{
                    return new Integer(p1.getValue().length()).compareTo(p2.getValue().length());
                });
        System.out.println(pairs);//[3=ab, 1=abc, 2=abcd, 4=abcde]

        pairs.sort( Comparator.comparing(p -> new Integer(p.getValue().length())));
        System.out.println(pairs);//[3=ab, 1=abc, 2=abcd, 4=abcde]

        //只可以按照key排序
        Map<String, Integer> treeMap = new TreeMap<>(new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return new Integer(o1.length()).compareTo(o2.length());
            }
        });
        treeMap.put("abc", 1);
        treeMap.put("abcd", 2);
        treeMap.put("ab", 3);
        treeMap.put("abcde", 4);
        System.out.println(treeMap);//{ab=3, abc=1, abcd=2, abcde=4}


        Map<Integer, String> hashMap = new HashMap<>();
        hashMap.put(1, "aec");
        hashMap.put(2, "abcd");
        hashMap.put(3, "ab");
        hashMap.put(4, "abcde");

        List<Map.Entry<Integer,String>> lists = new ArrayList<>(hashMap.entrySet());
        lists.sort((entry1,entry2)->{
            return new Integer(entry1.getValue().length()).compareTo(new Integer(entry2.getValue().length()));
        });
        System.out.println(lists);//[3=ab, 1=aec, 2=abcd, 4=abcde]

    }

    public static class ComparePairs implements Comparator{

        @Override
        public int compare(Object o1, Object o2) {
            Pair<Integer,String> pair1 = (Pair) o1;
            Pair<Integer,String> pair2 = (Pair) o2;
            return  new Integer(pair1.getValue().length()).compareTo(pair2.getValue().length());
        }
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值