Почему не работает TreeSet.contains ()? - PullRequest
5 голосов
/ 17 августа 2010
public class Empty {

    public static void main( String[] args ) {

        TreeSet<Class> classes = new TreeSet<Class>();
        classes.add( String.class );

        String test = new String();

        try{ 
            if( classes.contains(test.getClass()) ){
                System.out.println( "contains" );
            }
        }catch(ClassCastException cce){

            System.out.println( "Expected:  "  + classes );
            System.out.println( "But it was: " + test.getClass() );
        }
    }
}

Почему это выбрасывает ClassCastException?

Ответы [ 4 ]

8 голосов
/ 17 августа 2010

При создании экземпляра TreeSet без явного компаратора он ожидает, что вставленные элементы реализуют Comparable, но Class не реализует этот интерфейс.

Чтобы исправить, создайте компаратор для Class:

Comparator<Class> classComp = new Comparator<Class>()
{
    @Override
    public int compare(Class o1, Class o2)
    {
        return o1.getName().compareTo(o2.getName());
    }
};
TreeSet<Class> classes = new TreeSet<Class>(classComp);
3 голосов
/ 17 августа 2010

TreeSet - это упорядоченный набор, поэтому любой вставляемый элемент должен реализовывать Comparable (если не указан пользовательский Comparator).Class нет.

Если вам не нужен порядок, вы всегда можете использовать неупорядоченный набор, такой как HashSet .В противном случае вам нужно будет создать свой собственный порядок.

Из Javadoc (выделено мной):

Реализация NavigableSet на основе TreeMap. Элементы упорядочиваются с использованием их естественного упорядочения или с помощью компаратора, предоставляемого во время создания набора , в зависимости от того, какой конструктор используется.

Эта реализация обеспечивает гарантированные затраты времени журнала (n) длябазовые операции (добавить, удалить и содержать).

Обратите внимание, что упорядочение, поддерживаемое набором (независимо от того, предоставляется ли явный компаратор), должно соответствовать равным , если оно правильнореализовать интерфейс Set.(См. Comparable или Comparator для точного определения соответствия с equals.) Это так, потому что интерфейс Set определен в терминах операции equals, но экземпляр TreeSet выполняет все сравнения элементов, используя свой метод CompareTo (или сравнение), поэтому дваэлементы, которые считаются равными этим методом, с точки зрения множества равны.Поведение множества корректно определено, даже если его порядок не совпадает с равенством;он просто не соблюдает общий контракт интерфейса Set.

См. также: Comparator

1 голос
/ 17 августа 2010

Blockquote Почему это вызывает исключение ClassCastException?

Это было вызвано реализацией TreeMap, на которой основан TreeSet, являющийся набором ключей TreeMap.

java.lang.Class не реализует интерфейс java.lang.Comparable, поэтому он создает исключение ClassCastException.

0 голосов
/ 17 августа 2010

Фактическая ошибка java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.Comparable .Вот оно - TreeSet устанавливает порядок элементов.Если вы используете HashSet, все в порядке.

...