java - 为什么我们在 TreeMap 中转换为 Comparable

标签 java collections

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

 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。

最佳答案

TreeMap 文档提供以下信息:

A Red-Black tree based {@link NavigableMap} implementation. The map is sorted according to the {@linkplain Comparable natural ordering} of its keys, or by a {@link Comparator} provided at map creation time, depending on which constructor is used.

以下两个 TreeMap 构造函数(还有更多,但适用相同的规则)也适用于该特定规则。第一个假设 key 本质上是Comparable(并且每个插入的 key 都需要这样做),而第二个则提供了提供自定义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);
}

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

Since the key is already implementing Comparable and having the compare() overriden.

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

关于java - 为什么我们在 TreeMap 中转换为 Comparable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60476024/

相关文章:

java - 我正在尝试使用抽屉导航而不是 fragment 在 Activity 之间切换

java - 如何在实现接口(interface)后在另一个接口(interface)上强制执行类型

java - 更改 javax.json.JsonArray 中 json 元素的值

java - 在检查 ArrayList 中的 -1 值时 Collections.Frequency 返回 0

java - 将 JavaFX13 与 Java 13/8 一起使用并出现 JNI 错误?

Java:重载方法解析和可变参数——令人困惑的例子

java - 如何将 IOException 作为自定义运行时异常 Java 8 吞下

Scala:var List 与 val MutableList

java - 找到两个数组之间的非公共(public)元素

c# - 可以在 C# 4.0 中创建多类型 lambda 函数的单一多类型集合吗?