2009-05-16 6 views
6

विस्तारित करता है क्या निम्नलिखित कार्यान्वयन को एक प्रकार से सुरक्षित तरीके से करने का कोई तरीका है?जावा जेनिक्स मानचित्र पर डाल रहा है <स्ट्रिंग,? सूची <String>>

public void myMethod(Map<String, ? extends List<String>> map) 
{ 
    map.put("foo", Collections.singletonList("bar"); 
} 

उपर्युक्त कार्यान्वयन कार्य नहीं करता है। map.put() विधि को संकलित करने के लिए इसे Map<String, ? super List<String>> की आवश्यकता है। लेकिन myMethod इस तरह से सूची के किसी उप प्रकार को स्वीकार नहीं करेगा। इसलिए, मुझे इसके बजाय Map<String, ? extends List<String>> का उपयोग करना होगा। मैं इस समस्या को एक प्रकार से सुरक्षित तरीके से कैसे हल कर सकता हूं?

उत्तर

20
public void myMethod(Map<String, List<String>> map) { 
    map.put("foo", Collections.singletonList("bar")); 
} 

आप ? extends List के Map में Collections.singletonList() के List (वापसी प्रकार नहीं डाल सकते, क्योंकि वास्तविक प्रकार List के किसी भी कार्यान्वयन हो सकता है। उदाहरण के लिए, यह है नहीं एक सामान्य डाल करने के लिए सुरक्षित List में एक Map<String,LinkedList>List के बाद से एक LinkedList नहीं हो सकता है। हालांकि, हम आसानी से <String,List> के Map में एक LinkedList डाल सकते हैं।

मैं तुम्हें w लगता है अपने जेनेरिक सोचने पर ईरान। गैर-जेनेरिक वर्ग के लिए आपको ? extends का उपयोग करने की आवश्यकता नहीं है। उदाहरण के लिए, List<Object> कोई ऑर्डर जोड़ने के लिए Object, ? extends की आवश्यकता नहीं है। List<List<Foo>> केवल List<Foo> ऑब्जेक्ट्स लेगा और List<FooSubclass> ऑब्जेक्ट्स नहीं [जेनेरिक क्लास उनके पैरामीटर के आधार पर वारिस नहीं करते हैं]। यह वह जगह है जहां ? extends खेल में आता है। List<Foo> और List<FooSubclass> दोनों को List पर जोड़ने के लिए, प्रकार List<List<? extends Foo>> होना चाहिए।

+2

एक अच्छी व्याख्या के लिए +1 (अब जब आपके जेनेरिक दिखाई दे रहे हैं: पी)। –

+0

ओह। मैं सोचता रहता हूं कि चूंकि एसओएफ फ़िल्टर करता है वैसे भी यह एंग्लेड ब्रैकेट सामान को ठीक करता है। ओह अच्छा... – KitsuneYMG

6

Map<String, List<String> काम नहीं करेगा? क्या कोई विशेष कारण है कि आपके पास वाइल्डकार्ड होना चाहिए?

0

कल्पना करें कि किसी ने आपको Map<String, ArrayList<String>> पास किया है। जो मूल्य आप डाल रहे हैं वह संग्रह .singletonList का परिणाम है जो ArrayList नहीं है।

आप मानचित्र में सूची के किसी उप प्रकार को स्वीकार नहीं कर सकते हैं और फिर अपने स्वयं के, संभावित रूप से असंगत, उप प्रकार को जोड़ने में सक्षम होने की उम्मीद करते हैं।

4

संग्रह और जेनेरिक का एक साथ उपयोग करते समय एक बहुत ही सरल सिद्धांत है। इसे "द गेट एंड द पुट प्रिंसिपल" कहा जाता है:

जब आप केवल संग्रह से मूल्य प्राप्त करते हैं तो "विस्तृत" वाइल्डकार्ड का उपयोग करें, जब आप केवल संग्रह में मूल्य डालते हैं और उपयोग नहीं करते हैं तो "सुपर" वाइल्डकार्ड का उपयोग करें कोई वाइल्डकार्ड जब आप दोनों चाहते हैं और डालते हैं।

तो, जैसा कि आप देख सकते हैं, प्रारंभिक उदाहरण अमान्य है, इस सिद्धांत के अनुसार।