2015-07-12 6 views
0

Когда я пытаюсь запустить следующий код, я получаю сообщение об ошибке выполнения: java.lang.Integer cannot be cast to java.lang.Stringповедения в Java TreeSet при попытке Println содержания сырого типа множество

Set vals = new TreeSet(); 
vals.add(1); 
vals.add("two"); 
System.out.println(vals); 

Я пытался заменить его HashSet, HashLinkedSet, ArrayList и так далее, и все они побежали и напечатали ответ. Похоже, что только TreeSet не работает!

Мое предположение состоит в том, что это происходит из-за того, что TreeSet выполняет сравнение между объектами во время выполнения, что бы это не сработало.

Однако, я также знаю, что другие типы наборов (например, HashSet, например) должны делать одно и то же сравнение (но, может быть, в HashSet происходит сравнение между двумя хешированными значениями? И нет ли кастинга, который терпит неудачу?)

Почему это происходит?

ответ

0

TreeSet хранит значения в отсортированном порядке, следовательно, для сравнения нужно сравнить два элемента, а не просто равенство. Он внутренне использует TreeMap для хранения значений, а при вставке значений в TreeMap карта сравнивает ключи для odering. Ошибка возникает при сравнении, как видно из трассировки стека

Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String 
    at java.lang.String.compareTo(Unknown Source) 
    at java.util.TreeMap.put(Unknown Source) 
    at java.util.TreeSet.add(Unknown Source) 
    at Test.main(Test.java:10) 

подпись compareTo метода класса Строка выглядит следующим образом:

public int compareTo(String anotherString) 

Итак, когда вызов сделан к этому методу с int аргументом как в вашем коде набор содержит значение int, ошибка времени выполнения происходит в отношении класса cast

Similary, если вы добавили String сначала в набор и затем добавили Integer, как показано на рисунке b Elow:

Set vals = new TreeSet(); 
    vals.add("two"); 
    vals.add(1); 
    System.out.println(vals); 

Вы бы видели, исключение из Integer класса

Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer 
    at java.lang.Integer.compareTo(Unknown Source) 
    at java.util.TreeMap.put(Unknown Source) 
    at java.util.TreeSet.add(Unknown Source) 
    at Test.main(Test.java:10) 

В случае HashSet, эта проблема не возникает, потому что элементы сравниваются равенства.

Сигнатура equals метода класса Строка выглядит следующим образом:

public boolean equals(Object anObject) 

Здесь, как вы можете видеть, входной параметр java.lang.Object, и целое может быть передан этой функции без каких-либо ошибки. Реализация внутренне использует instanceof оператор для проверки типа совместимости, и позволяет избежать ClassCastException

Вы можете сказать, что это разница между тем, как compareTo и equals реализуются в результате в этой ошибке.

+0

так почему не исключение для HashSet? – Maya

+0

Обновлен ответ –

+0

@ user5108422 Вы в порядке с предоставленным оправданием? Если да, пожалуйста, примите ответ –