Warum funktioniert TreeSet.contains () Arbeit?
-
29-09-2019 - |
Frage
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() );
}
}
}
Warum dies eine ClassCastException
wirft?
Lösung
Wenn TreeSet
ohne expliziten Komparator instanziiert wird, es Elemente eingefügt erwartet Comparable
zu implementieren, aber Class
implementieren diese Schnittstelle nicht.
Um dies zu beheben, erstellen Sie einen Komparator für 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);
Andere Tipps
TreeSet
ist eine geordnete Menge, so jedes Element einfügen Sie Comparable
implementieren müssen (es sei denn, Sie eine benutzerdefinierte Comparator
angeben). Class
nicht.
Wenn Sie nicht über die Bestellung benötigen, können Sie immer eine ungeordnete Menge verwenden wie HashSet . Andernfalls müssen Sie mit einer Bestellung von Ihrer eigenen zu entwickeln.
Von der Javadoc (Hervorhebung von mir):
Eine NavigableSet Implementierung basiert auf ein TreeMap. Die Elemente sind bestellt mit ihrer natürlichen Ordnung, oder durch eine Komparator bei eingestellten Schaffung Zeit , je nachdem, welcher Konstruktor verwendet wird.
Diese Implementierung bietet garantierter log (n) Zeitkosten für die Grundoperationen (Hinzufügen, Entfernen und enthält).
Beachten Sie, dass die Bestellung durch eine gepflegte Satz (mit oder ohne eine explizite Komparator vorgesehen ist) müssen im Einklang mit equals , wenn es zu die Set-Schnittstelle korrekt umzusetzen. (Siehe Vergleichbare oder Vergleicher für eine genaue Definition im Einklang mit Das entspricht.) Ist so, weil das Set Schnittstelle wird in Bezug auf die definierte Betrieb ist gleich, aber ein TreeSet Beispiel führt die gesamte Element mit Vergleichen seiner compareTo (oder Vergleich) Verfahren, so dass zwei Elemente werden durch dieses Verfahren als gleich sind, vom Standpunkt des Satzes entspricht. Das Verhalten eines Satzes ist wohldefiniert selbst wenn seine Bestellung ist inkonsistent mit equals; es nicht nur die gehorchen Rahmenvertrag der Set-Schnittstelle.
Siehe auch: Vergleicher
Blockquote Warum dies einen Classcast werfen?
Es war Ursache durch die Umsetzung der TreeMap, der TreeSet, dass ein Schlüsselsatz von TreeMap ist basiert auf ihr.
java.lang.Class nicht die java.lang.Comparable-Schnittstelle implementieren, so wird es eine Ausnahme von Classcast werfen.
Der tatsächliche Fehler ist java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.Comparable
. Hier ist sie - TreeSet erlegt eine Ordnung auf den Elementen. Wenn Sie einen HashSet verwenden, ist alles in Ordnung.