2017-10-22 11 views
9

मैं जावा स्रोत कोड पढ़ रहा हूँ के विस्तार और मैं नीचे के रूप में चीजों को मिल गया है करता है:
http://www.java2s.com/Code/JavaAPI/java.util/newTreeSetEComparatorsuperEc.htm
क्यों TreeSet <E> के निर्माता ई के पैरामीटर सुपर स्वीकार करने के बजाय ई

मैं डॉन ' टी समझ में नहीं आता कि इस कन्स्ट्रक्टर का पैरामीटर <? super E> क्यों है।

मेरी समझ के रूप में, <? super E> के बजाय <? extend E> होना चाहिए क्योंकि यदि ई तुलनीय है, तो ई के बच्चे तुलनीय होना चाहिए जबकि ई के माता-पिता नहीं हो सकते हैं।

उत्तर

14

पढ़ के तीन वर्गों पर ध्यान दें: Drink, Juice extends Drink, और OrangeJuice extends Juice

यदि मुझे TreeSet<Juice> चाहिए, तो मुझे एक तुलनित्र की आवश्यकता है जो किसी भी दो रस की तुलना करेगी। बेशक Comparator<Juice> ऐसा करेगा।

Comparator<Drink> यह भी करेगा, क्योंकि यह किसी भी दो पेय की तुलना करने में सक्षम है, और इस प्रकार कोई भी दो रस।

Comparator<OrangeJuice> ऐसा नहीं करेगा। अगर मैं रस के अपने सेट में AppleJuice जोड़ना चाहता था, तो यह तुलनित्र के साथ संगत नहीं है क्योंकि यह केवल संतरे के रस की तुलना कर सकता है।

7

आप केले का एक क्रमबद्ध सेट बनाते हैं। ऐसा करने के लिए, आपको केले की तुलना करने में सक्षम होना चाहिए। इस प्रकार आप ऐसा करने के लिए केले के तुलनित्र का उपयोग कर सकते हैं। लेकिन अगर आपके पास एक तुलनित्र है जो कि किसी भी प्रकार के फल (केले सहित) को सॉर्ट कर सकता है, तो वह भी काम करेगा। तो आप अपने केले को क्रमबद्ध करने के लिए Comparator<Fruit> या यहां तक ​​कि Comparator<Food> का भी उपयोग कर सकते हैं।

यही कारण है कि Comparator<? super E> का उपयोग किया जाता है।

यदि यह Comparator<? extends E> था, तो आप Comparator<DriedBanana> के साथ केले का एक सेट बनाने में सक्षम होंगे। लेकिन यह काम नहीं करेगा: सूखे केले के तुलनित्र केवल सूखे केले की तुलना कर सकते हैं। सभी प्रकार के केले नहीं।

अधिक जानकारी के लिए भी What is PECS (Producer Extends Consumer Super)?

4

यह बजाय क्योंकि अगर ई तुलनीय है हो सकता है, ई के बच्चों के माता पिता ई के नहीं हो सकता है, जबकि तुलनीय होना चाहिए।

ComparatorComparable ऑब्जेक्ट्स पर भरोसा नहीं करता है।
इसे अक्सर वैकल्पिक या पूरक के रूप में भी उपयोग किया जाता है।

वास्तव में, इस निर्माता

public TreeSet(Comparator<? super E> comparator) {...} 

हो सकता था:

public TreeSet(Comparator<E> comparator) {... } 

लेकिन एक कम घिरे वाइल्डकार्ड निर्दिष्ट करके, JDK डेवलपर्स Comparator की इजाजत दी जा करने के लिए द्वारा ग्राहक वर्गों के लिए और अधिक लचीलापन प्रदान की वर्तमान कक्षा के उदाहरणों और अभिभावक वर्ग के उदाहरणों के साथ अंतःक्रियाशील। कुछ मामलों में, यह समझ में आता है।

अब इस:

public TreeSet(Comparator<? extend E> comparator) { 

के रूप में यह मतलब है कि आप एक compare() विधि पैरामीटर के रूप में उपवर्ग प्रकार निर्दिष्ट के साथ समाप्त कर सकते हैं मान्य नहीं हो सकता है।
लेकिन Set के तत्वों में एक विशिष्ट उपclass के उदाहरण हो सकते हैं लेकिन न केवल।

इस कोड की कल्पना कीजिए:

TreeSet<CharSequence> set = new TreeSet<>(new Comparator<String>() { 

    @Override 
    public int compare(String o1, String o2) { 
     ... 
    } 
}); 

set.add("string"); 
set.add(new StringBuilder()); 
... 

मैं String रों तुलना चाहते हैं, लेकिन SetString उदाहरणों को रख सकती है लेकिन यह भी की CharSequence ऐसे StringBuilder, CharBuffer, आदि ...
के रूप में और अगर CharSequence था किसी भी उपवर्ग abstract नहीं, इसमें उनके उदाहरण भी शामिल हो सकते हैं।

इस उदाहरण के साथ, हम समझते हैं कि अवधारणा Comparator<? extend E> गलत है।

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