首页 > 解决方案 > 为什么我们在 TreeMap 中转换为 Comparable

问题描述

我正在学习Java,并在APICollections中遇到了以下代码,TreeMap

 if (key == null)
                throw new NullPointerException();
            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);

为什么我们Comparable首先需要强制转换?由于key已经实施Comparable并已被compare()覆盖。为什么我们不能打电话key.compare(t.key)

关键是实现 Comparable。

标签: javacollections

解决方案


TreeMap文档提供了以下信息:

基于红黑树的 {@link NavigableMap} 实现。地图根据其键的 {@linkplain Comparable natural ordering} 或在地图创建时提供的 {@link Comparator} 排序,具体取决于使用的构造函数。

以下两个TreeMap构造函数(还有更多,但适用相同的规则)也适用于该特定规则。第一个假设密钥是自然的Comparable(并且每个插入的密钥都需要这样做),而第二个提供了提供自定义的可能性Comparator

public TreeMap() {
    comparator = null;
}

public TreeMap(Comparator<? super K> comparator) {
    this.comparator = comparator;
}

确定应该使用哪种行为,实现经常验证是否Comparator已初始化。

final int compare(Object k1, Object k2) {
    return comparator == null ? ((Comparable<? super K>)k1).compareTo((K)k2)
        : comparator.compare((K)k1, (K)k2);
}

因此,您的以下假设不适用:

由于密钥已经实现了 Comparable 并覆盖了 compare() 。

K的键Map可以是任意类型,不限于Comparable。这提供了更大的灵活性,因为有时您无法使一个类相互比较(例如,如果它来自第三方库)或者一个类在逻辑上没有自然顺序。我建议阅读 和 的Comparable文档Comparator


推荐阅读