• TreeMap排序探寻


    TreeMap本身是默认带有升序排序的策略的,如果要修改其排序规则,有2种方式。

    1、实体元素实现Comparable接口,重写compareTo方法。

    2、实现Cpmparator 重写compare方法。

    以第二种方法为例,该方法会返回一个数字,根据该数字来判定如何进行排序。

    1. Map<Integer,List<String>> map = new <Integer, List<String>>(
    2. new Comparator<Integer>() {
    3. public int compare(Integer obj1, Integer obj2) {
    4. if(obj1 > obj2){
    5. return 正数 or 负数 or 0
    6. }
    7. }
    8. });

    返回数值的排序规则为:

            返回正数 :升序排序。

            返回负数: 降序排序。

            返回 0    : 抛弃数据,返回0是指key相同,TreeMap继承自AbstractMap其定义是不允许出现key相同的情况。

    那么它是如何通过返回值完成排序的呢?

            我们先看下TreeMap的数据结构:

                    --TreeMap的每个存储元素为Entry类

    1. static final class Entry<K,V> implements Map.Entry<K,V> {
    2. K key;
    3. V value;
    4. Entry<K,V> left;
    5. Entry<K,V> right;
    6. Entry<K,V> parent;
    7. boolean color = BLACK;
    8. 。。。
    9. }

            TreeMap的数据结构是红黑树结构,从其中的成员变量命名就可以看出。

    看完结构后再打开关键方法put()看下是如何判断的:

    1. public V put(K key, V value) {
    2. 。。。
    3. //如果自定义排序器不为空则进入
    4. if (cpr != null) {
    5. do {
    6. parent = t;
    7. //自定义排序规则的返回
    8. cmp = cpr.compare(key, t.key);
    9. if (cmp < 0)
    10. t = t.left;
    11. else if (cmp > 0)
    12. t = t.right;
    13. else
    14. return t.setValue(value);
    15. } while (t != null);
    16. }
    17. 。。。
    18. }

    在TreeMap进行put时,如果自定义比较器存在,则会根据自定义的compare返回来判断,如果小于0(-1)则放在节点的左边,如果大于0(1)则放在节点的右边。

    看到这里存的部分基本关于排序的都看了,在取的时候,也用到了排序器

    1. final Entry<K,V> getEntryUsingComparator(Object key) {
    2. @SuppressWarnings("unchecked")
    3. K k = (K) key;
    4. Comparator<? super K> cpr = comparator;
    5. if (cpr != null) {
    6. Entry<K,V> p = root;
    7. while (p != null) {
    8. //排序器
    9. int cmp = cpr.compare(k, p.key);
    10. if (cmp < 0)
    11. p = p.left;
    12. else if (cmp > 0)
    13. p = p.right;
    14. else
    15. return p;
    16. }
    17. }
    18. return null;
    19. }

  • 相关阅读:
    beego语言golang编程语言安装bee : 无法将“bee”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。
    响应式网站建站源码系统+完整的搭建教程
    在Ubuntu 20.04上安装和配置MySQL 8:详细指南和远程访问设置
    【lesson7】git的介绍及使用
    Filebeat自定义index和fields
    多系统架构设计思考
    Linux远程管理协议
    D-Bus:busctl的使用
    golang的defer踩坑汇总
    rviz添加qt插件
  • 原文地址:https://blog.csdn.net/Mr__forget/article/details/125539609