2011-04-19 21 views
11

क्या कुछ कुंजी दिए गए मानचित्र से सभी मान प्राप्त करने का कोई शानदार तरीका है?जावा/गुवा में कुछ कुंजी के लिए मानचित्र से सभी मान प्राप्त करें?

मैं इस तरह एक विधि चाहते हैं:

public static <K, V> Collection<V> getAll(Map<K, V> map, Collection<K> keys) 

या पहले से ही एक अमरूद तरीका है?

+0

तुम सच में वापस एक मानचित्र के बजाय मूल्यों की एक संग्रह प्राप्त करने के लिए करना चाहते हैं? इसे बनाने की प्रक्रिया में, आप कुंजी और मूल्यों के बीच संबंध खो देंगे। –

उत्तर

18

यह आप कैसे काम करने के लिए विधि चाहते हैं पर निर्भर करता है। उदाहरण के लिए, कि mapएक में नहीं हैं keys में तत्वों) सिर्फ नजरअंदाज कर दिया जाना चाहिए या वे बी) लौटे मूल्यों संग्रह में null के रूप में प्रतिनिधित्व किया जा चाहिए या कि सी) एक त्रुटि होना चाहिए? यह भी विचार करें कि क्या आप लाइव व्यू या मूल्यों वाला एक अलग संग्रह चाहते हैं।

एक के लिए, मेरी प्राथमिकता होगी:

Collection<V> values = Collections2.transform(
    Collections2.filter(keys, Predicates.in(map.keySet()), 
    Functions.forMap(map)); 

इस कुंजी है कि नक्शे में वास्तव में कर रहे हैं और साथ ही अपेक्षाकृत कुशल होना चाहिए के लिए मूल्यों को परिणाम को सीमित करता है, भले ही नक्शा बहुत बड़ा है आप चाहते हैं कि चाबियों के सेट से। बेशक, आप उस परिणाम को किसी दूसरे संग्रह में कॉपी करना चाहते हैं, इसके आधार पर आप इसके साथ क्या करना चाहते हैं।

बी के लिए, आप Functions.forMap(map, null) को छोड़कर @ माइकल ब्रेवर-डेविस के समाधान का उपयोग करेंगे।

सी के लिए, आप पहली बार है कि map.keySet().containsAll(keys) की जाँच करें और एक त्रुटि है, तो false, तो @Michael Brewer-डेविस के समाधान का उपयोग फेंक ... लेकिन ध्यान रखें कि जब तक आप फिर एक और संग्रह करने के लिए परिणाम की नकल की करना चाहते हैं , map से एक प्रविष्टि को निकालने से किसी बिंदु पर लौटाए गए संग्रह का उपयोग करके कोड के लिए IllegalArgumentException हो सकता है।

+0

यदि आपको शून्य मानों की परवाह नहीं है, तो आप ए और बी: संग्रह मान = संग्रह 2.filter (संग्रह 2.transform (कुंजी, Functions.forMap (मानचित्र, शून्य)), Predicates.notNull()) को भी जोड़ सकते हैं; यह प्रति प्रवेश केवल एक लुकअप करता है (Predicates.in() में एक लुकअप करने और फ़ंक्शंस में एक और करने के बजाय।forMap()) –

3

आप मान सकते हैं कि, Predicate में गुजरने वाले गुवा के Maps.filteredKeys() का उपयोग करें, जो आपकी वांछित कुंजी से मेल खाता है, लेकिन यह वास्तव में मैन्युअल पुनरावृत्ति से बेहतर नहीं है।

3

का उपयोग करते हुए अमरूद: Collections2.transform(keys, Functions.forMap(map));

+1

ध्यान रखें कि मानचित्र में नहीं होने वाली कुंजी के लिए रूपांतरित संग्रह में किसी तत्व तक पहुंचने का प्रयास करने के परिणामस्वरूप 'अवैध अवैधकरण 'के रूप में परिणाम होगा ... यदि संभव हो तो डिफ़ॉल्ट के साथ ओवरलोड बेहतर हो सकता है। – ColinD

12

मैं skaffman के उत्तर से सहमत हूं, सिर्फ अपने निष्कर्ष के साथ नहीं (मुझे लगता है कि यह मैन्युअल पुनरावृत्ति से बेहतर है)।

यहाँ यह स्पष्ट है:

public static <K, V> Collection<V> getAll(Map<K, V> map, Collection<K> keys) { 
    return Maps.filterKeys(map, Predicates.in(keys)).values(); 
} 

इसके अलावा, यहाँ एक गैर अमरूद संस्करण है:

public static <K, V> Collection<V> getAll(Map<K, V> map, Collection<K> keys) { 
    Map<K, V> newMap = new HashMap<K, V>(map); 
    newMap.keySet().retainAll(keys); 
    return newMap.values(); 
} 
+2

इसके लिए 'फ़िल्टरकेस' का उपयोग करने वाली समस्याएं हैं ए) इसे 'मानचित्र' की प्रत्येक प्रविष्टि के माध्यम से पुनरावृत्ति की आवश्यकता होती है, भले ही 'कुंजी' बहुत छोटी हो (दूसरी तरफ विधि के लिए कम संभावना है इस तरह), और बी) यदि 'कुंजी' संग्रह में तेज़ 'शामिल' कार्यान्वयन नहीं है, तो मानचित्र में प्रत्येक प्रविष्टि के लिए इसे कॉल करने से कॉल की जटिलता के क्रम में वृद्धि होगी। मेरे द्वारा दिए गए कोड में इनमें से कोई भी समस्या नहीं है। गैर-अमरूद संस्करण के लिए, मुझे लगता है कि एक लूप बेहतर होगा ... परिणामस्वरूप खाली होने पर भी आपके संस्करण को मानचित्र की पूरी प्रति को स्मृति में रखने की आवश्यकता है। – ColinD

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