zoukankan      html  css  js  c++  java
  • JDK作泛型比较时为什么把逻辑代码写两遍

    疑惑:JDK作泛型比较时为什么不用一个compare函数把比较封装起来,而是把逻辑代码写两遍(Comparable 和 Comparator)?

    在 PriorityQueue 和 TreeMap 中都如此

    TreeMap put源码

        /**
         * Associates the specified value with the specified key in this map.
         * If the map previously contained a mapping for the key, the old
         * value is replaced.
         *
         * @param key key with which the specified value is to be associated
         * @param value value to be associated with the specified key
         *
         * @return the previous value associated with {@code key}, or
         *         {@code null} if there was no mapping for {@code key}.
         *         (A {@code null} return can also indicate that the map
         *         previously associated {@code null} with {@code key}.)
         * @throws ClassCastException if the specified key cannot be compared
         *         with the keys currently in the map
         * @throws NullPointerException if the specified key is null
         *         and this map uses natural ordering, or its comparator
         *         does not permit null keys
         */
        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) { do { parent = t; cmp = cpr.compare(key, t.key); if (cmp < 0) t = t.left; else if (cmp > 0) t = t.right; else return t.setValue(value); } while (t != null); } else { 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; }
        // Little utilities
    
        /**
         * Compares two keys using the correct comparison method for this TreeMap.
         */
        @SuppressWarnings("unchecked")
        final int compare(Object k1, Object k2) {
            return comparator==null ? ((Comparable<? super K>)k1).compareTo((K)k2)
                : comparator.compare((K)k1, (K)k2);
        }

    红色段落将有无comparator的情况分开,写了两遍逻辑代码。

    就算已经写好了compare函数封装了比较,也不用,甚至只是用它去类型检查。

    我的理解是减少判空次数,提升效率。

    若有知情人士,请在评论区留言告诉我,不胜感激。

  • 相关阅读:
    【洛谷P1297】单选错位【期望】
    【洛谷P1297】单选错位【期望】
    【POJ1201】Intervals【差分约束】
    【POJ1201】Intervals【差分约束】
    【洛谷P3275】糖果【差分约束】【负环】
    【洛谷P3275】糖果【差分约束】【负环】
    【洛谷P1768】天路【负环】【二分】【数论】
    【洛谷P1768】天路【负环】【二分】【数论】
    【JZOJ4256】平均数【二分】
    【JZOJ4256】平均数【二分】
  • 原文地址:https://www.cnblogs.com/GY8023/p/13955274.html
Copyright © 2011-2022 走看看