2012-10-06 28 views
8

मैंने कुछ कोड here पोस्ट किया जो पोस्टर के पास एक समस्या का सही ढंग से हल किया गया। ओपी डुप्लिकेट को हटाना चाहता था और कुछ विशेष वस्तुओं को सूची के शीर्ष पर ले जाना चाहता था। मैंने एक विशेष Comparable वर्ग के साथ TreeSet का उपयोग किया जो Locale को लपेटता था जो वे चाहते थे कि वे प्राप्त करने के लिए काम कर रहे थे।सेट्स के साथ समान और तुलनात्मक

मैं तो सोच को मिला ... के रूप में आप कर ... कि मैं compareTo विधि से 0 लौटने, एक equals कार्यान्वयन से true वापस लौट कर नहीं इस आधार पर डुप्लीकेट को नष्ट किया गया था के रूप में एक सही तरीके से एक नकली इंगित करने के लिए क्या करने की जरूरत होगी Set में (Set के definition से)।

मुझे इस तकनीक का उपयोग करने के लिए कोई आपत्ति नहीं है, लेकिन क्या मैं अनूदित फीचर पर विचार कर रहा हूं? क्या मैं यह मानने के लिए सुरक्षित हूं कि इस तरह की चीज आगे बढ़ने से काम जारी रहेगा?

+0

श्री Nurkiewicz बताते हैं के रूप में देखें, इस, व्यवहार निर्दिष्ट किया जाता है तो यह सुरक्षित है। मैं सहमत हूं कि यह आश्चर्य की बात है, यद्यपि! –

उत्तर

17

यह इस बहुत अच्छी तरह से JavaDoc of TreeSet (बोल्ड मेरा) में प्रलेखित है की तरह लगता है:

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

Set<BigDecimal> decimals = new HashSet<BigDecimal>(); 
decimals.add(new BigDecimal("42")); 
decimals.add(new BigDecimal("42.0")); 
decimals.add(new BigDecimal("42.00")); 
System.out.println(decimals); 

decimals अंत में तीन मान हैं क्योंकि 42, 42.0 और 42.00 बराबर नहीं जहाँ तक equals() प्रकार हैं:

यहाँ only (?) JDK class कि Comparable लागू करता है लेकिन equals() साथ संगत नहीं है का एक उदाहरण है संबंधित है। लेकिन अगर आप HashSet को TreeSet के साथ प्रतिस्थापित करते हैं, तो परिणामी सेट में केवल 1 आइटम (42 - जो पहले जोड़ा गया था) क्योंकि BigDecimal.compareTo() का उपयोग करते समय उन सभी को बराबर माना जाता है।

यह दिखाता है कि TreeSet एक तरह से "टूट" जब equals() के साथ संगत नहीं प्रकार का उपयोग कर रही है। यह अभी भी ठीक से काम करता है और सभी परिचालन अच्छी तरह परिभाषित हैं - यह Set वर्ग के अनुबंध का पालन नहीं करता है - यदि दो वर्ग equal() नहीं हैं, तो उन्हें डुप्लिकेट नहीं माना जाता है।

भी

+0

दिलचस्प है कि 'ConcurrentSkipListSet' दस्तावेज़ों में ऐसी कोई टिप्पणी नहीं है। – OldCurmudgeon

+1

@OldCurmudgeon यह वास्तव में [सॉर्टेडसेट के जावाडोक] में भी निर्दिष्ट है (http://docs.oracle.com/javase/7/docs/api/java/util/SortedSet.html) (और ट्रीसेट और ConcurrentSkipListSet दोनों लागू करें इंटरफेस)। – assylias

+0

तो यह करता है !! अच्छी पकड़। – OldCurmudgeon