为什么 TreeSet.contains() 不起作用?

发布于 2024-09-14 20:25:14 字数 601 浏览 8 评论 0原文

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

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() );
        }
    }
}

Why does this throw a ClassCastException?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

笑梦风尘 2024-09-21 20:25:14

当实例化没有显式比较器的 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);

When instantiating TreeSet without an explicit comparator, it expects inserted elements to implement Comparable, but Class does not implement this interface.

To fix, create a comparator for 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);
李白 2024-09-21 20:25:14

TreeSet 是一个有序集,因此您插入的任何元素都必须实现 Comparable(除非您指定自定义 Comparator)。 Class 没有。

如果不需要排序,则始终可以使用无序集,例如 哈希集。否则,您需要自己制定订单。

来自 Javadoc(强调我的):

基于的 NavigableSet 实现
树形图。 元素是有序的
使用它们的自然顺序,或者通过
在创建集合时提供比较器
时间
,取决于哪个构造函数
已使用。

这个实现提供了
保证 log(n) 时间成本
基本操作(添加、删除和
包含)。

请注意由a维护的排序
设置(无论是否明确
提供比较器)必须是
与 equals 一致,如果是的话
正确实现Set接口。
(请参阅比较或比较器了解
一致的精确定义
等于。)这是因为集合
接口是根据以下定义的
equals操作,但是一个TreeSet
实例执行所有元素
使用其compareTo(或
Compare)方法,所以两个元素
通过这种方法被认为相等的是,
从集合的角度来看,相等。
集合的行为是明确定义的
即使它的顺序不一致
与平等;它只是不遵守
Set接口的通用契约。


另请参阅:比较器

TreeSet is an ordered set, so any element you insert must implement Comparable (unless you specify a custom Comparator). Class does not.

If you don't need the ordering, you can always use an unordered set such as HashSet. Otherwise, you'll need to come up with an ordering of your own.

From the Javadoc (emphasis mine):

A NavigableSet implementation based on
a TreeMap. The elements are ordered
using their natural ordering, or by a
Comparator provided at set creation
time
, depending on which constructor
is used.

This implementation provides
guaranteed log(n) time cost for the
basic operations (add, remove and
contains).

Note that the ordering maintained by a
set (whether or not an explicit
comparator is provided) must be
consistent with equals
if it is to
correctly implement the Set interface.
(See Comparable or Comparator for a
precise definition of consistent with
equals.) This is so because the Set
interface is defined in terms of the
equals operation, but a TreeSet
instance performs all element
comparisons using its compareTo (or
compare) method, so two elements that
are deemed equal by this method are,
from the standpoint of the set, equal.
The behavior of a set is well-defined
even if its ordering is inconsistent
with equals; it just fails to obey the
general contract of the Set interface.

See also: Comparator

忱杏 2024-09-21 20:25:14

块引用
为什么这会抛出 ClassCastException?

这是由TreeMap的实现引起的,TreeSet是TreeMap的一个键集,它是基于它的。

java.lang.Class没有实现java.lang.Comparable接口,因此会抛出ClassCastException异常。

Blockquote
Why does this throw a ClassCastException?

It was cause by the implementation of TreeMap, the TreeSet that is a key set of TreeMap is based on it.

java.lang.Class does not implement the java.lang.Comparable interface,thus it will throw an exception of ClassCastException.

﹉夏雨初晴づ 2024-09-21 20:25:14

实际错误是java.lang.ClassCastException: java.lang.Class无法转换为java.lang.Comparable
。就是这样 - TreeSet 对元素强加了排序。如果你使用HashSet,一切都可以。

The actual error is java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.Comparable
. Here it is - TreeSet imposes an ordering on the elements. If you use a HashSet, all is OK.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文