为什么TreeSet的add方法在不同的JRE中表现不同?

时间:2016-06-17 04:04:20

标签: java set classcastexception treeset

我尝试将Employee类的对象添加到TreeSet中。我没有实现Comparable或Comparator接口。但是add方法代码在不同的系统中表现不同。为什么这样?以下代码段: -

import java.util.Set;
import java.util.TreeSet;

public class TreeSetTest {
public static void main(String[] args) {

    Set<Employee> set = new TreeSet<Employee>();
    set.add(new Employee());
//  set.add(new Employee());
//  set.add(new Employee());
 }
}

在当前系统(Win 10)上,我是否写了一次或三次set.add()方法。它总是在运行时抛出ClassCastException。 但谈到这个问题 - Why does TreeSet throws ClassCastException 那里的用户写道,当他只使用一次add方法时,他不会得到异常。

另外,在另一个系统(Win 7)中,昨天我尝试添加对象3次,调用set方法三次,并且没有ClassCastException !!集合的大小仅为1,因此似乎没有多个对象被添加到集合中。

那么添加方法的不同类型行为可能是什么原因?

1 个答案:

答案 0 :(得分:4)

TreeSet.add()委托给TreeMap.put(),它在Java 6和Java 8中有不同的行为。

Java 6

public V put(K key, V value) {
    Entry<K,V> t = root;
    if (t == null) {
        // TBD:
        // 5045147: (coll) Adding null to an empty TreeSet should
        // throw NullPointerException
        //
        // compare(key, key); // type check
        root = new Entry<K,V>(key, value, null);
        size = 1;
        modCount++;
        return null;
    }
    ...

Java 8

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;
    }
    ...

正如您所看到的,早期版本由于某种原因已将compare()行注释掉,但它在后来的版本中被添加回来。因此,您在第一个元素中看到的例外情况。

另见:Why TreeSet can be used as a key for TreeMap in jdk 1.6?