2010-08-17 28 views
5
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.contains() काम नहीं करता है?

+0

अपवाद में और जानकारी होनी चाहिए कि क्या गलत हुआ ... अपवाद और स्टैक ट्रेस मुद्रित करना लगभग हमेशा एक अच्छा विचार है (केवल पकड़ ब्लॉक के अंदर 'cce.printStackTrace() 'जोड़ें) –

उत्तर

8

एक स्पष्ट तुलनित्र के बिना 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); 
+0

+1 तुलनित्र, हालांकि मैं तुलना का उपयोग किया होगा ToIgnoreCase() ;-) – cadrian

+3

@candrian - वोट के लिए धन्यवाद। लेकिन आप मामले को अनदेखा कैसे करेंगे? क्लास नाम जावा में केस-असंवेदनशील नहीं हैं, और नाम (स्रोत में दिए गए अनुसार) क्लासफ़ाइल के अंदर संग्रहीत किया जाता है। – mdma

3

TreeSet एक आदेश दिया गया सेट है, इसलिए आपके द्वारा डाले गए किसी भी तत्व को Comparable लागू करना होगा (जब तक कि आप एक कस्टम Comparator निर्दिष्ट नहीं करते)। Class नहीं करता है।

यदि आपको ऑर्डरिंग की आवश्यकता नहीं है, तो आप हमेशा एक अनियंत्रित सेट का उपयोग कर सकते हैं जैसे कि HashSet। अन्यथा, आपको अपने आदेश के साथ आने की आवश्यकता होगी।

जावाडोक (जोर मेरा) से

:

एक NavigableSet कार्यान्वयन एक ट्री-मैप पर आधारित है। तत्वों को उनके प्राकृतिक आदेश का उपयोग करके का आदेश दिया गया है, या सेट निर्माण समय पर प्रदान किया गया तुलनाकर्ता, जो कि कन्स्ट्रक्टर का उपयोग किया जाता है, के आधार पर उपयोग किया जाता है।

इस कार्यान्वयन बुनियादी कार्यों के लिए गारंटी लॉग (एन) समय लागत (जोड़ने के लिए, हटाने और शामिल है) प्रदान करता है।

कि नोट आदेश एक सेट (एक स्पष्ट तुलनित्र प्रदान की जाती है या नहीं) द्वारा बनाए रखा संगत के बराबर होती है अगर इसे सही ढंग से सेट इंटरफ़ेस को लागू करने के लिए है साथ होना चाहिए। (देखें तुलनीय या के अनुरूप की एक सटीक परिभाषा के लिए तुलनाकारी बराबर होती है।) यह इसलिए है क्योंकि सेट इंटरफ़ेस के बराबर होती है आपरेशन के मामले में परिभाषित किया गया है, लेकिन एक TreeSet उदाहरण, अपना compareTo (का उपयोग कर सभी तत्व तुलना करता है या तुलना करें) विधि, इसलिए दो तत्वों को इस विधि के बराबर समझा जाता है, सेट के स्टैंडपॉइंट से बराबर है। एक सेट का व्यवहार अच्छी तरह से परिभाषित है, भले ही उसका ऑर्डर असंगत बराबर है; यह सेट इंटरफ़ेस के सामान्य अनुबंध का पालन करने में विफल रहता है।

यह भी देखें: Comparator

0

वास्तविक त्रुटि java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.Comparable है। यहां यह है - वृक्षारोपण तत्वों पर एक आदेश लगाता है। यदि आप हैशसेट का उपयोग करते हैं, तो सब ठीक है।

1

Blockquote क्यों यह एक ClassCastException फेंक करता है?

यह ट्रीमैप के कार्यान्वयन के कारण था, ट्रीसेट जो ट्रीमैप का एक प्रमुख सेट है, उस पर आधारित है।

java.lang.Class java.lang.Comparable इंटरफ़ेस को लागू नहीं करता है, इस प्रकार यह ClassCastException की एक अपवाद फेंक देते हैं।

संबंधित मुद्दे