欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

TreeMap通过Comparator/Comparable实现自定义排序

程序员文章站 2022-05-23 14:17:00
...

在向TreeMap中添加对象时,要求对象要么实现了Comparable接口,要么在创建TreeSet时传入了该对象的Comparator比较器,两者选其一即可,否则在添加对象时就会报错。

  • 实现Comparable接口
    TreeMap通过Comparator/Comparable实现自定义排序
  • 传入Comparator比较器
    TreeMap通过Comparator/Comparable实现自定义排序

在TreeSet的add(object)方法是通过调用TreeMap的put(key,value)方法来实现的,key为待添加的对象object,value为一个不可变的常量。
  • 在put方法中首先判断有没有key对象的比较器,如果没有的化就调用key值自身的comparaTo()方法(前提是key对象实现了Comparable接口)
 public V put(K key, V value) {
        Entry<K,V> t = root;
        if (t == null) {
            compare(key, key); // type (and possibly null) check

            root = new Entry<>(key, value, null);
            size = 1;
            modCount++;
            return null;
        }
        int cmp;
        Entry<K,V> parent;
        // split comparator and comparable paths
        Comparator<? super K> cpr = comparator;
        if (cpr != null) { //如果比较器不为空,则通过比较器来比较key的大小
            do {
                parent = t;
                cmp = cpr.compare(key, t.key);
                if (cmp < 0)  // 比较的结果小于0,放在左子节点
                    t = t.left; 
                else if (cmp > 0) // 比较的结果大于0,放在右子节点
                    t = t.right;
                else
                    return t.setValue(value); // 结果等于零,代表key值相等,覆盖value值
            } while (t != null);
        }
        else { // 当没有传入Comparator时,就使用key对象的compareTo方法
            if (key == null)
                throw new NullPointerException();
            @SuppressWarnings("unchecked")
                Comparable<? super K> k = (Comparable<? super K>) key;
            do {
                parent = t;
                cmp = k.compareTo(t.key);
                if (cmp < 0)
                    t = t.left;
                else if (cmp > 0)
                    t = t.right;
                else
                    return t.setValue(value);
            } while (t != null);
        }
        Entry<K,V> e = new Entry<>(key, value, parent);
        if (cmp < 0)
            parent.left = e;
        else
            parent.right = e;
        fixAfterInsertion(e);
        size++;
        modCount++;
        return null;
    }

TreeMap和TreeSet都是通过Comparator中的Compare方法或者Comparable中的compareTo方法或者来判断元素是否相等。