2016-03-01 6 views
23

क्यों Collections.sort(List<T>) हस्ताक्षर हैCollections.sort() घोषणा:</p> <pre><code>public static <T extends Comparable<? super T>> void sort(List<T> list) </code></pre> <p>और नहीं: क्यों <? super T> बजाय <T>

public static <T extends Comparable<T>> void sort(List<? extends T> list) 
  • मैं समझता हूँ कि वे दोनों एक ही काम करेगा उद्देश्य; तो ढांचा डेवलपर्स पहले विकल्प का उपयोग क्यों किया?
  • या ये घोषणाएं वास्तव में अलग हैं?

उत्तर

19

आपका प्रस्तावित हस्ताक्षर शायद जावा -8 में काम करेगा। हालांकि पिछले जावा संस्करणों में अनुमान इतना स्मार्ट नहीं था। ध्यान दें कि आपके पास List<java.sql.Date> है। ध्यान दें कि java.sql.Datejava.util.Date बढ़ाता है जो Comparable<java.util.Date> लागू करता है। जब आप संकलित करते हैं

List<java.sql.Date> list = new ArrayList<>(); 
Collections.sort(list); 

यह जावा -7 में पूरी तरह से काम करता है। यहां T अनुमानित java.sql.Date है जो वास्तव में Comparable<java.util.Date> है जो Comparable<? super java.sql.Date> है। हालांकि के अपने हस्ताक्षर की कोशिश करते हैं:

public static <T extends Comparable<T>> void sort(List<? extends T> list) {} 

List<java.sql.Date> list = new ArrayList<>(); 
sort(list); 

यहाँ Tjava.util.Date के रूप में अनुमान लगाया जाना चाहिए। हालांकि जावा 7 विनिर्देश इस तरह की अनुमान की अनुमति नहीं देता है।

Main.java:14: error: method sort in class Main cannot be applied to given types; 
     sort(list); 
     ^
    required: List<? extends T> 
    found: List<Date> 
    reason: inferred type does not conform to declared bound(s) 
    inferred: Date 
    bound(s): Comparable<Date> 
    where T is a type-variable: 
    T extends Comparable<T> declared in method <T>sort(List<? extends T>) 
1 error 

प्रकार निष्कर्ष बहुत जावा-8 में सुधार किया गया था: इसलिए इस कोड जब जावा-7 के तहत संकलित जावा-8 के साथ संकलित किया जा सकता है, लेकिन विफल रहता है। अलग जेएलएस chapter 18 अब इसे समर्पित है, जबकि जावा -7 में नियम were बहुत आसान है।

+1

लेकिन स्थिर <टी ऑब्जेक्ट और तुलनात्मक > टी अधिकतम (संग्रह सी) कैसे काम करता है ठीक है ... क्या यह फिर से एक अनुमान मुद्दा है? – prvn

+0

@prvn, यहां आपके तुलनात्मक हस्ताक्षर में 'तुलनात्मक ' की बजाय 'तुलनात्मक ' है। '<टी तुलनात्मक > शून्य प्रकार (सूची सूची) बढ़ाता है '' भी काम करेगा, लेकिन 'जोड़ना होगा? 'अधिकतम' विधि में उचित होने पर टी 'पूरी तरह से अनावश्यक है (जैसा कि' अधिकतम' मान देता है)। –

+6

एक और बिंदु है। जब आपके पास वाइल्डकार्ड प्रकार 'सूची सूची' है, तो आप वाइल्डकार्ड प्रकारों के काम के तरीके के कारण विधि के अंदर 'list.set (अनुक्रमणिका, list.get (anotherIndex))' नहीं कर सकते हैं। इसे कैप्चर करने वाली आंतरिक सहायक विधि के साथ छेड़छाड़ की जा सकती है? टी को किसी अन्य प्रकार परिवर्तनीय में बढ़ाता है (या अनियंत्रित संचालन का उपयोग करके आंतरिक कार्यान्वयन अक्सर करता है), लेकिन फिर भी, वाइल्डकार्ड के बिना एक प्रकार संशोधित होने वाली सूची के लिए क्लीनर है। – Holger

4

वे भिन्न हैं क्योंकि ? super TT से कम प्रतिबंधित है। यह एक Lower Bounded Wildcard (लिंक किए गए जावा ट्यूटोरियल का कहना है कि भाग में)

अवधि List<Integer> उत्तरार्द्ध जबकि किसी भी प्रकार है की एक सूची से मेल खाता है, पूर्व क्योंकि केवल प्रकार Integer की एक सूची से मेल खाता है List<? super Integer> से अधिक प्रतिबंधात्मक है Integer का एक सुपरटेप।

T साथ Integer बदलें और यह एक Tया एक java.lang.Object का मतलब है।

+0

लेकिन मैं सॉर्ट() .. के तर्क में flexibilty बढ़ रहा हूँ? विस्तारित, – prvn

+0

हां, कोई भी नहीं कहा कि 'सूची 'सूची ' जैसा ही है। दूसरा संस्करण 'विस्तार' का उपयोग करता है और सवाल यह है कि यह इसे बराबर बनाता है। – JojOatXGME

+0

मुझे नहीं लगता कि आपका उत्तर सीधे प्रश्न से संबंधित है। – yuxh

9
// 0 
public static <T extends Comparable<? super T>> void sort0(List<T> list) 

// 1 
public static <T extends Comparable<T>> void sort1(List<? extends T> list) 

ये हस्ताक्षर भिन्न होती हैं क्योंकि वे प्रकार T और T की परिभाषा में Comparable के प्रकार तर्क के बीच संबंधों पर विभिन्न आवश्यकताओं को लागू।

उदाहरण के लिए मान लीजिए कि आप इस वर्ग के होते हैं:

class A implements Comparable<Object> { ... } 

तो अगर आप

List<A> list = ... ; 
sort0(list); // works 
sort1(list); // fails 

कारण sort1 विफल रहता है कि वहाँ कोई प्रकार T है कि दोनों ही के बराबर है है और यह है, या सूची के प्रकार का एक सुपरटेप है।

यह पता चला है कि A वर्ग खराब है, क्योंकि Comparable के लिए कुछ निश्चित आवश्यकताओं को पूरा करने की आवश्यकता है। विशेष रूप से तुलना को उलट करने से परिणाम के संकेत को उलट दिया जाना चाहिए। हम A के उदाहरण को Object पर तुलना कर सकते हैं लेकिन इसके विपरीत नहीं, इसलिए इस आवश्यकता का उल्लंघन किया जाता है। लेकिन ध्यान दें कि अर्थशास्त्रComparable की आवश्यकता है और टाइप सिस्टम द्वारा लगाया नहीं गया है। केवल टाइप सिस्टम को ध्यान में रखते हुए, दो sort घोषणाएं वास्तव में अलग हैं।

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