为什么treeset.contains()不起作用?
-
29-09-2019 - |
题
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
?
解决方案
实例化时 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);
其他提示
TreeSet
是有序集,因此您插入的任何元素都必须实现 Comparable
(除非您指定自定义 Comparator
). Class
才不是。
如果您不需要订购,则可以随时使用无序的集合 哈希集. 。否则,您需要提出自己的订购。
来自Javadoc(重点是我的):
基于Treemap的Navigableset实现。 这些元素是使用其自然订购或通过在创建时间提供的比较器来订购的, ,取决于使用哪个构造函数。
此实现为基本操作提供了保证的日志(n)时间成本(添加,删除并包含)。
注意 一组维护的订购(是否提供了显式比较器)必须与平等一致 如果要正确实现集合接口。 (有关与平等一致的精确定义,请参见可比较或比较器。)之所以如此,是因为设置界面是根据平等操作定义的,但是TreesEt实例使用其比较(或比较)方法执行所有元素比较,所以两个从集合的角度来看,通过这种方法认为相等的元素是相等的。即使其订购与平等不一致,该集合的行为也是明确的。它只是未能遵守集合接口的一般合同。
也可以看看: 比较器
BlockQuote为什么要抛出ClassCastException?
这是由于Treemap的实现而导致的,这是Treemap的一组TreeTET是基于它的。
java.lang.class不会实现java.lang.com.parable界面,因此它将引发classcastException的例外。
实际错误是 java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.Comparable
. 。在这里 - 树材料对元素施加了订购。如果您使用标签,一切都可以。