2012-03-06 26 views
12

यह जावा (1.6) संग्रह इंटरफ़ेस का हिस्सा है:जेनेरिक संग्रह

public interface Collection<E> extends java.lang.Iterable<E> { 
    /* ... */ 
    boolean containsAll(java.util.Collection<?> objects);  
    boolean addAll(java.util.Collection<? extends E> es);  
    boolean removeAll(java.util.Collection<?> objects);  
    boolean retainAll(java.util.Collection<?> objects); 
    /* ... */ 
} 

addAll क्यों है <? extends E> जबकि removeAll है <?>

उत्तर

12

मुझे नहीं पता था, मैं googled।http://www.ibm.com/developerworks/java/library/j-jtp01255/index.html

भाग को कॉपी करना:: मैं इस explaination यहाँ मिल गया

generifed संग्रह एपीआई है कि अक्सर पहली बार में भ्रमित की

एक तत्व containsAll(), removeAll(), और retainAll के हस्ताक्षर है() । आप निकालना() और removeAll के लिए हस्ताक्षर उम्मीद कर सकते हैं() होने के लिए:

interface Collection<E> { 
    public boolean remove(E e); // not really 
    public void removeAll(Collection<? extends E> c); // not really 
} 

लेकिन यह वास्तव में है:

interface Collection<E> { 
    public boolean remove(Object o); 
    public void removeAll(Collection<?> c); 
} 

ऐसा क्यों है? फिर, जवाब पिछड़ा संगतता में निहित है। X.remove (ओ) का इंटरफ़ेस अनुबंध का अर्थ है "यदि ओ एक्स में निहित है, इसे हटा दें, अन्यथा, कुछ भी नहीं करें।" यदि एक्स एक सामान्य संग्रह है, तो x के प्रकार पैरामीटर के साथ टाइप-संगत होने की आवश्यकता नहीं है। removeAll() अगर अपने तर्क प्रकार संगत (Collection<? extends E>), तो कोड के कुछ दृश्यों कि कानूनी थे इससे पहले कि जेनरिक अवैध, बन जाएगा यह एक तरह था केवल प्रतिदेय होने की generified रहे थे:

// a collection of Integers 
Collection c = new HashSet(); 
// a collection of Objects 
Collection r = new HashSet(); 
c.removeAll(r); 

यदि उपरोक्त टुकड़ा स्पष्ट तरीके से उत्पन्न किया गया था (सीए Collection<Integer> और आर Collection<Object>), तो उपरोक्त कोड संकलित नहीं होगा अगर निकालने के हस्ताक्षर() को हस्ताक्षर करने के लिए Collection<? extends E> होने की आवश्यकता है, तो नो-ऑप होने के बजाय। कक्षा पुस्तकालयों को उत्पन्न करने के प्रमुख लक्ष्यों में से एक मौजूदा कोड के अर्थशास्त्र को तोड़ना या परिवर्तित करना था, इसलिए हटाएं(), removeAll(), retainAll(), और includeAll() को कमजोर प्रकार की बाधा के साथ परिभाषित किया जाना चाहिए हो सकता है कि उन्हें जेनेरिक के लिए खरोंच से फिर से डिजाइन किया गया हो।

0

जावा विलोपन के माध्यम से जेनरिक लागू करता है। ये जानकारी केवल संकलन समय के लिए ही हैं। मुझे लगता है कि जावा संग्रह डिजाइनरों ने प्री-जेनेरिक जावा संस्करण के साथ अधिक बढ़िया संगतता बरकरार रखने के लिए ऐसा किया था।

+2

वह यही नहीं पूछ रहा है। – SLaks

+0

क्षमा करें अगर मैं गलत समझा। :( – Nicocube

0

जब आप कोई ऑब्जेक्ट जोड़ते हैं, तो इसे मुख्य प्रकार के उप-वर्ग (या उप-सबक्लास, आदि) की आवश्यकता होती है। जब आप किसी ऑब्जेक्ट को हटाते हैं, तो यह इसे संग्रह के प्रकार के रूप में लौटाता है। कार्रवाई में polymorphism का यह एक अच्छा उदाहरण है।

0

जो आप को हटाने का प्रयास करते हैं, इसकी परवाह कौन करता है?

जोड़ना कुछ और है; हम अपने संग्रह में कुछ अजीब के साथ खत्म नहीं करना चाहते हैं।

अनुरोध के अनुसार; एक उदाहरण:

import java.util.ArrayList; 
import java.util.Collection; 
import java.util.List; 

public class Main { 

    private static class A { 

    } 

    public static void main(String[] args) { 
     Collection<A> collection_A = new ArrayList<A>(); 

     Collection<String> collection = new ArrayList<String>(); 

     // no problem to try and remove things that wouldn't be there in the first place; either way, they are gone afterwards 
     collection.removeAll(collection_A); 

     // we can't allow this; you would end up with things in your collection that don't belong there 
     collection.addAll(collection_A); 
    } 

} 
+0

क्या आप इसे एक विशिष्ट उदाहरण या दो के साथ चित्रित कर सकते हैं? – NPE

2

आप अपने संग्रह में आइटम जोड़ने जब आप सुनिश्चित करें कि वे एक निश्चित प्रकार है होना चाहता हूँ।

जब आप उन्हें हटाते हैं, तो केवल संग्रह में ही हटा दिए जाते हैं। उनके प्रकार के बावजूद।

3

<?><? extends E> से कम प्रतिबंधित है।

सेब के संग्रह से नारंगी हटाने में कुछ भी गलत नहीं है; सेब के संग्रह में एक नारंगी जोड़कर बहुत सी चीजें गलत हैं।

+0

मुझे पता है कि आपका क्या मतलब है ... हर जगह ऑरिज रस था। उन दोनों को कभी भी साथ नहीं मिला। +1 –

+0

हां, लेकिन चूंकि * जोड़ने * के लिए कोई रास्ता नहीं है सेब के संग्रह में नारंगी, संग्रह में संभवतः एक नारंगी नहीं हो सकता है, इसलिए 'removeAll()' ' 'ले सकता है, है ना? – NPE

+2

@aix: यह आपको' फल '(या यहां तक ​​कि 'ऑब्जेक्ट') और अपने संग्रह से अपने सभी सेब हटा दें। – SLaks

7

किसी भी प्रकार E के तत्वों से युक्त संग्रह के लिए, addAll इनपुट संग्रह E की न सिर्फ से निपटने के लिए सक्षम होना चाहिए, लेकिन इसके उपवर्गों के सभी के साथ-साथ। इसलिए <? extends E>। इस के बिना, आप एक List<Integer> के सभी तत्वों को एक List<Number>, जो स्पष्ट रूप से नहीं सही होगा नहीं जोड़ सके। *

हटाने के लिए, सीमा इतनी सख्ती से सेट करने की आवश्यकता नहीं है, और तत्वों को दूर करने की कोशिश कर में कोई बुराई नहीं है कुछ पूरी तरह से असंबंधित प्रकार के संग्रह का। जैसे आपके पास Number एस का संग्रह हो सकता है, जिसके बारे में आपको पता होता है कि इसमें केवल Integer एस है, इसलिए इसे removeAll पर List<Integer> पर गुजरना ठीक काम करना चाहिए, और यह संकलक को अस्वीकार करने के लिए बेवकूफ होगा।

ध्यान दें कि according to the Javadoc, removeAll कार्यान्वयन के आधार पर वैकल्पिक रूप से ClassCastException फेंक सकता है।

* इसके पीछे कारण यह है कि जावा में, जेनरिक अपरिवर्तनीय हो रहा है। अधिक जानकारी के लिए, उदा। देखें this thread

0

वर्णन करने के लिए क्या कहा गया है एक साधारण उदाहरण:

public class Test { 

    public static void main(String[] args) { 
     List<String> l = new ArrayList<String>(); 
     System.out.println(l.remove(new Object())); //false 
     System.out.println(l.contains(new Object())); //false 
//  l.add(new Object()); // does not compile 
    } 

} 
0

निकालने के लिए प्रतिबंध की जरूरत नहीं है, इसलिए केवल <?>, लेकिन जोड़ने हम जांच करने के लिए और उसके बाद प्रकार की सुरक्षा के लिए जोड़ने के लिए, है तो addAll जबकि प्रतिबंध <? extends E>

0

जोड़ने के साथ आप जेनेरिक प्रकार के उप-प्रकार के सभी तत्वों को जोड़ने में सक्षम होना चाहते हैं। इसमें List<String> के सभी तत्वों को List<Object> में शामिल करना शामिल है। हम इस संग्रह या किसी उप-प्रकार में संग्रहीत प्रकार वाले किसी भी संग्रह को स्वीकार करने के लिए ? extends E का उपयोग करते हैं।

boolean addAll(java.util.Collection<? extends E> es); 
List<Number> numbers = ...; 
List<Integer> integers = ...; 
numbers.addAll(integers);//works  

boolean addAll(java.util.Collection<E> es); 
numbers.addAll(integers);//does not work E != Integer 

हम ? कि के रूप में उपयोग नहीं कर सकते जेनरिक द्वारा प्रदान की किसी भी सुरक्षा को दूर करेंगे।

boolean addAll(java.util.Collection<? extends E> es); 
List<Number> numbers = ...; 
List<Integer> integers = ...; 
List<String> strings = ...; 
numbers.addAll(integers);//works 
numbers.addAll(strings);//error 

boolean addAll(java.util.Collection<?> es); 
numbers.addAll(strings);//works - now we have strings in our Number collection 

हम ? का उपयोग नंबर की सूची से एक स्ट्रिंग को दूर करने के अभ्यस्त एक List<Number> को प्रभावित कोशिश कर के बाद से वस्तुओं को हटाने के लिए कर सकते हैं।

boolean removeAll(java.util.Collection<?> objects); 
List<Objects> objects = ...; 
List<Integer> integers = ...; 
List<Number> numbers = ...; 
numbers.removeAll(objects);//works 
numbers.removeAll(integers);//works 

boolean removeAll(java.util.Collection<? extends E> objects); 
numbers.removeAll(objects);//does not work 
numbers.removeAll(integers);//works 

boolean removeAll(java.util.Collection<? super E> objects); 
numbers.removeAll(objects);//works 
numbers.removeAll(integers);//does not work 
संबंधित मुद्दे