Java:首次添加调用时触发的TreeSet compareTo方法

以下Java代码利用TreeSet收集从类MyClass派生的对象,该类未实现Comparable接口,也没有compareTo()方法来执行对象之间的比较.通过不提供该比较方法,我们希望在添加第二个对象(而不是第一个对象)的过程中引发异常,因为只有一个对象的比较不明确.

JDK:1.7

题:
为什么在第一个添加tree.add(m1)上触发compareTo()?

码:

package javaapplication1;

import java.util.*;

class MyClass
{
    int _x;
    MyClass(int x)
    {
        _x = x;
    }
}

public class JavaApplication1 
{
     public static void main(String[] args) 
     {
         MyClass m1 = new MyClass(5);
         MyClass m2 = new MyClass(3);

         TreeSet tree = new TreeSet();
         tree.add(m1);
         tree.add(m2);
     }
}

解决方法:

TreeSet在TreeMap的顶部实现.因此TreeSet.add()调用TreeMap.put(Object,Object)方法.请参阅以下内容:

public V put(K key, V value) {
        Entry<K,V> t = root;
        if (t == null) {
            compare(key, key); //this is the culprit

            root = new Entry<>(key, value, null);
            size = 1;
            modCount++;
            return null;
        }
    ……………
    ……………
    ……………
}

现在,因为根为空,所以流程将进入if(t == null){因此调用compare(key,key).

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

在compare方法内部,它是类型转换k1,k2 Comparable,并且您的类未实现Comparable,因此出现以下异常:

Exception in thread "main" java.lang.ClassCastException: .

此代码根据JDK 1.7.

上一篇:java-如何使用二进制搜索从排序的TreeSet中检索元素?


下一篇:Java学习之路(四十三)| 集合(七)—— TreeSet