Why doesn't TreeSet.contains() work?

拜拜、爱过 提交于 2019-12-10 13:49:23

问题


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?


回答1:


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



回答2:


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




回答3:


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.




回答4:


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.



来源:https://stackoverflow.com/questions/3501997/why-doesnt-treeset-contains-work

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!