当我尝试运行以下代码时,我收到运行时错误:java.lang.Integer cannot be cast to java.lang.String
Set vals = new TreeSet();
vals.add(1);
vals.add("two");
System.out.println(vals);
我尝试用HashSet,HashLinkedSet,ArrayList等替换它,然后它们都运行并打印出答案。看起来只有TreeSet无法正常工作!
我的假设是发生这种情况是因为TreeSet在运行时对对象进行了比较,这会失败。
但是,我也知道其他类型的集合(例如HashSet)需要进行相同的比较(但是在HashSet中,比较发生在两个散列值之间?并且没有失败的转换?)
为什么会这样?
答案 0 :(得分: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)
String类的compareTo
方法的签名如下所示:
public int compareTo(String anotherString)
因此,当在代码中使用int
参数调用此方法时,该集合包含int
值,运行时错误发生在类强制转换
同样,如果您先将String添加到set中,然后添加Integer,如下所示:
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 ,则不会发生此问题,因为要比较元素是否相等。
String类的equals
方法的签名如下:
public boolean equals(Object anObject)
在这里,正如您所看到的,输入参数是java.lang.Object,并且可以将整数传递给此函数而不会出现任何错误。该实现在内部使用instanceof
运算符来检查类型兼容性,并避免ClassCastException
您可以说compareTo
和equals
的实施方式之间存在差异导致此错误。