【Java基础】使用TreeMap升序|降序|随机|去重排序

map简介

在讲解Map排序之前,我们先来稍微了解下map。map是键值对的集合接口,它的实现类主要包括:HashMap,TreeMap,Hashtable以及LinkedHashMap等。其中这四者的区别如下(简单介绍):

  1. HashMap:最常用Map,它根据key的HashCode 值来存储数据,根据key可以直接获取它的Value,同时它具有很快的访问速度。HashMap最多只允许一条记录的key值为Null(多条会覆盖);允许多条记录的Value为 Null。非同步的。线程不安全

  2. TreeMap: 能将保存的数据根据key排序,默认是按升序,也可指定排序的比较器,当用Iterator 遍历TreeMap时,得到的记录是排过序的。TreeMap不允许key的值为null。非同步的。线程不安全

  3. Hashtable: 与 HashMap类似,不同的是:key和value的值均不允许为null;它支持线程的同步,即任一时刻只有一个线程能写Hashtable,因此也导致了Hashtale在写入时会比较慢。

  4. LinkedHashMap: 保存了记录的插入顺序,在用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的.在遍历的时候会比HashMap慢。key和value均允许为空,非同步的。线程不安全

简单总结为:

  • HashMap,Hashtable:无序
  • Treemap:默认是升序(以key作为标准)
  • Linkedhashmap:默认是插入数据时的顺序

map集合的key特性就是不重复的,所以不需要编写去重逻辑, 某些情况下可以通过重写对象的equals&hashCode方法来实现去重

使用TreeMap进行默认升序排序

默认按字典顺序进行升序排序

    @Test
    public void testDefault() {
        // 默认的TreeMap升序排列
        Map<String, String> treeMap = new TreeMap<>();
        treeMap.put("444", "赵六");
        treeMap.put("222", "李四");
        treeMap.put("111", "张三");
        treeMap.put("333", "王五");
        treeMap.put("333", "王五");
        
        for (Map.Entry<String, String> entrySet : treeMap.entrySet()) {
            System.out.println(entrySet.getKey() + "------" + entrySet.getValue());
        }
    }

执行结果:
在这里插入图片描述

使用TreeMap按key进行自定义的升序|降序|反转顺序

  1. 通过TreeMap<K,V>向其构造方法 TreeMap(Comparator<? super K> comparator)传入我们自定义的比较器 即Comparator可实现按键排序。
  2. 不传Comparator,默认按字典顺序进行升序
    @Test
    public void testKey() {
		//按键排序
		// 1.声明TreeMap并并使用比较器Comparator定义比较规则
        Map<String, String> treeMap = new TreeMap<>(new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                // 升序
                /* if (o1.compareTo(o2) < 0) {
                    return -1;
                }else if (o1.compareTo(o2) > 0) {
                    return 1;
                } else{
                    return  0;
                }*/


                // 降序
                /* if (o1.compareTo(o2) < 0) {
                    return 1;
                }else if (o1.compareTo(o2) > 0) {
                    return -1;
                } else{
                    return  0;
                }*/

                //升序
                //return o1.compareTo(o2);

                //降序
                return o2.compareTo(o1);
                
                //顺序反转
                //return -1;
            }
        });


        treeMap.put("444", "赵六");
        treeMap.put("222", "李四");
        treeMap.put("111", "张三");
        treeMap.put("333", "王五");
        treeMap.put("444", "赵六");
    

		// 2.遍历并打印排序结果
        for (Map.Entry<String, String> entrySet : treeMap.entrySet()) {
            System.out.println(entrySet.getKey() + "------" + entrySet.getValue());
        }
    }

执行结果:降序
在这里插入图片描述

执行结果:反转顺序
在这里插入图片描述

使用TreeMap按value进行排序

  1. 将待排序Map中的所有元素置于一个列表List<Map.Entry<String, String>>
  2. 使用Collections的一个静态方法 sort(List list, Comparator<? super T> c) ,通过比较器Comparator定义排序规则,此处使用降序规则
  3. 声明LinkedHashMap用于保存排序后的结果,LinkedHashMap可以保证Map中元素与排序后的List中的元素的顺序一致(不声明也可以.声明只是为了保存元素顺序一定正确
     @Test
    public void testValue() {
        //1. 待排序的集合
        Map<String, String> hashMap = new HashMap<>();
        hashMap.put("赵六", "444");
        hashMap.put("李四", "222");
        hashMap.put("张三", "111");
        hashMap.put("王五", "333");
        hashMap.put("赵六", "444");

        // 1. 将待排序Map中的所有元素置于一个列表中
        List<Map.Entry<String, String>> entryList = new ArrayList<Map.Entry<String, String>>(hashMap.entrySet());

        // 2. 使用Collections的一个静态方法 sort(List<T> list, Comparator<? super T> c) ,通过比较器Comparator定义排序规则,此处使用降序规则
        Collections.sort(entryList, new Comparator<Map.Entry<String, String>>() {
            @Override
            public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
                // 降序
                if (o1.getValue().compareTo(o2.getValue()) < 0) {
                    return 1;
                } else if (o1.getValue().compareTo(o2.getValue()) > 0) {
                    return -1;
                } else {
                    return 0;
                }

                // 升序
                /*if (o1.getValue().compareTo(o2.getValue()) < 0) {
                    return -1;
                } else if (o1.getValue().compareTo(o2.getValue()) > 0) {
                    return 1;
                } else {
                    return 0;
                }*/

                // 反转顺序
               /* return  -1;*/
            }
        });


        //3. 用于保存排序后的结果,LinkedHashMap可以保证Map中元素与排序后的List中的元素的顺序一致
        Map<String, String> linkedHashMap = new LinkedHashMap<>();

        //使用迭代器
//        Iterator<Map.Entry<String, String>> entryIterator = entryList.iterator();
//        while (entryIterator.hasNext()) {
//            Map.Entry<String, String> entry = entryIterator.next();
//            linkedHashMap.put(entry.getKey(), entry.getValue());
//
//        }

        //使用迭代器
//        Set<Map.Entry<String, String>> linkedHashMapEntry = linkedHashMap.entrySet();
////       Iterator<Map.Entry<String,String>> linkIterator =  linkedHashMapEntry.iterator();
////       while (linkIterator.hasNext()){
////           Map.Entry<String,String> entry = linkIterator.next();
////           System.out.println(entry.getKey()+"-----"+entry.getValue());
////       }

        //使用foreach
        for (Map.Entry<String,String> entry: entryList){
            linkedHashMap.put(entry.getKey(), entry.getValue());
        }

        //使用foreach
        for (Map.Entry<String,String> entry :linkedHashMap.entrySet()) {
            System.out.println(entry.getKey()+"-----"+entry.getValue());
        }
    }

执行结果:降序
在这里插入图片描述

使用TreeMap按key进行随机排序

通过在比较器Comparator的compare使用Math.random()方法 比较两个变量的 相减值实现随机排序

 @Test
    public void testRandom(){
        //1. 待排序的集合
        Map<String, String> treeMap = new TreeMap<>(new Comparator<String>() {

            //2.声明随机数,进行随机判断大小
            @Override
            public int compare(String o1, String o2) {
                int randomOne = (int) (Math.random() * 10);
                int randomTwo = (int) (Math.random() * 10);
                return  randomOne - randomTwo;
            }
        });
        treeMap.put("444", "赵六");
        treeMap.put("222", "李四");
        treeMap.put("111", "张三");
        treeMap.put("333", "王五");

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

执行结果:
第一次
在这里插入图片描述
第二次
在这里插入图片描述
第三次
在这里插入图片描述

Map转成List使用Collections.shuffle()随机排序

只供参考,不推荐使用此方法进行map随机排序, Collections.shuffle 比较适合对 List<Integer>进行排序

    /**
     * Map转List 随机排序
     */
    @Test
    public void testRandomByCollectionsUtil() {
        //1. 未排序map
        Map<String, Object> 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("g", 50);
        unsortMap.put("m", 2);
        unsortMap.put("f", 9);

        //2. 获取map所有的key转换成 LinkedList
        List<String> list = new LinkedList(unsortMap.keySet());

        //3. 调用随机排序 Collections.shuffle()
        Collections.shuffle(list);

        Map<String, Object> result = new HashMap<>();
        for (int i = 0; i < list.size(); i++) {
            String jsonString = list.get(i);
            result.put(jsonString, unsortMap.get(jsonString));
        }
        for (Map.Entry<String, Object> entry : result.entrySet()) {
            System.out.println(entry.getKey() + " " + entry.getValue());
        }
    }
发布了62 篇原创文章 · 获赞 109 · 访问量 5308

猜你喜欢

转载自blog.csdn.net/qq877728715/article/details/102880170