2010-04-23 18 views
6

जावा संग्रह में addAll (..) विधि के लिए सही प्रकार का तर्क क्या है? अगर मैं ऐसा कुछ करता हूं:जावा जेनेरिक और ऐडअल विधि

List<? extends Map<String, Object[]>> currentList = new ArrayList<Map<String, Object[]>>(); 
Collection<HashMap<String, Object[]>> addAll = new ArrayList<HashMap<String, Object[]>>(); 
// add some hashmaps to the list.. 
currentList.addAll(addAll); 

मुझे समझ में आता है कि मुझे दोनों चर शुरू करने की आवश्यकता है। हालांकि, मुझे संकलन त्रुटि मिलती है (ग्रहण से):

Multiple markers at this line 
    - The method addAll(Collection<? extends capture#1-of ? extends Map<String,Object[]>>) in the type List<capture#1-of ? extends Map<String,Object[]>> is not applicable for the arguments (List<capture#2-of ? extends 
    Map<String,Object[]>>) 
    - The method addAll(Collection<? extends capture#1-of ? extends Map<String,Object[]>>) in the type List<capture#1-of ? extends Map<String,Object[]>> is not applicable for the arguments 
    (Collection<HashMap<String,Object[]>>) 

मैं क्या गलत कर रहा हूं?

+1

क्या आप दोनों 'currentList' और 'newElements' दोनों के लिए अपनी घोषणाएं दिखाने के लिए संपादित कर सकते हैं? – elduff

+0

मुझे लगता है कि 'newElements' को 'addAll' माना जाता है, मैंने कोड तय कर लिया है। – Jherico

उत्तर

7

आप केवल सम्मिलित कर सकते हैं नहीं मिल सकता है T के उदाहरण List<T> में।

प्रकार List<? extends Map<X,Y>> एक अज्ञात प्रकार T जो extends Map<X,Y> की एक सूची के लिए खड़ा है। उदाहरण के लिए, यह List<LinkedHashMap<X,Y>> के लिए खड़ा हो सकता है। जाहिर है, आप ऐसी सूची में सामान्य HashMap<X,Y> नहीं डाल सकते हैं।

आप शायद चाहते हैं:

List<Map<String, Object[]>> currentList; 

या आप कर सकता है यदि आप वास्तव में लचीला होना चाहते हैं:

List<? super Map<String, Object[]>> currentList; 

जो तुम जैसे पागल काम करने की अनुमति होगी:

currentList = new ArrayList<Map<? super String, ? extends Object[]>>(); 

आप एंजेलिका लैंगर जेनरिक एफएक्यू, विशेष रूप से the section about wildcards पढ़ना चाहेंगे।

0

आपका प्रश्न मूल रूप से इस करने पर निर्भर करता: के रूप में आप का वर्णन

public static <T extends Collection<?>> void foo(T t) { 
T x = null; 
x.addAll(t); 
} 

यह अनिवार्य रूप से एक ही त्रुटि के साथ विफल हो जाएगा। इसे ठीक करने के लिए इन पंक्तियों के साथ कुछ कोशिश करें।

public static <T extends Collection<Y>, Y> void foo(T t) { 
T x = null; 
x.addAll(t); 
} 

वैकल्पिक रूप से, अपने उदाहरण में आप

List<Map<String, Object[]>> currentList; 

जेनेरिक्स बालों को बहुत शीघ्र हो जाता है करने के लिए

List<? extends Map<String, Object[]>> currentList; 

बदल सकता है इसके बाद के संस्करण यदि आप के आसपास अनिर्दिष्ट प्रकार गुजर शुरू करने के लिए प्रयास करें।

1

आप ऐसी सूची में जेनेरिक विशेषताओं के साथ किसी भी विधि को कॉल नहीं कर सकते हैं। असल में, ? extends Foo कहता है "कुछ ऐसा जो Foo बढ़ाता है", लेकिन आप नहीं जानते कि यह कुछ क्या है। जब वह प्रकार वापस आ जाता है, तो आप कह सकते हैं कि लौटाया गया मूल्य Foo या कुछ उप प्रकार है। लेकिन किसी भी दिए गए मान के लिए आप यह नहीं कर सकते कि यह ? extends Foo जेनेरिक से मेल खाता है।

संक्षेप में: आप currentList घोषणा या यह List को कास्ट ( जेनरिक के बिना) बदल सकते हैं और एक चेतावनी या के साथ रहती है (यदि आप जानते हैं कि आप क्या कर रहे हैं) के लिए उसे दबाने की जरूरत है।

8

extendssuper द्वारा बदलें।

addAll() अपने आप में एक ? extends T तर्क लेता है और है कि काम नहीं करेगा जब T? extends Map<K, V> है। परिवर्तन के साथ यह प्रभावी ढंग से ? extends ? super Map<K, V> बन जाएगा।

लेकिन फिर भी, ? extends (या ? super) को हटाने के लिए बेहतर है। यह इस विशेष मामले में अनिवार्य है। बस List<Map<String, Object[]>> का उपयोग करें। addAll() प्रभावी रूप से ? extends Map<String, Object[]>> ले जाएगा।

+0

'मौजूदा सूची' को 'सूची <के रूप में घोषित क्यों करें? सुपर मैप <स्ट्रिंग, ऑब्जेक्ट [] >> ', और न केवल' सूची <मानचित्र <स्ट्रिंग, ऑब्जेक्ट [] >> '? उसके कोड का यह हिस्सा मेरे लिए अनावश्यक लगता है। –

+0

@ मैट: यह भी मैंने पिछले अनुच्छेद में जो कहा था :) – BalusC

6

बस याद रखें:

<? extends ...> के लिए, आप नहीं बातें (शून्य को छोड़कर) इसे में डाल सकते हैं <? super ...> के लिए

, आप चीजों (वस्तु को छोड़कर) इससे बाहर

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