2015-04-08 3 views
6

मैं कुछ Map वस्तुओं है कि अलग ढंग से टाइप किया मूल्यों V1...VN है, जो इस सवाल के प्रयोजन के लिए एक महाप्रकार * का हिस्सा नहीं है के साथ एक ही प्रकार K द्वारा keyed रहे हैं:कुछ मानचित्रों से अलग-अलग व्युत्पन्न मानचित्र मानों के साथ परिणामी मानचित्र को कुशलतापूर्वक फ़िल्टर और एकत्रित करने के लिए कैसे?

Map<K, V1> kv1 
Map<K, V2> kv2 
Map<K, V3> kv3 
... 
Map<K, VN> kvN 

मैं एक जिसके परिणामस्वरूप नक्शा बनाने की जरूरत इन मानचित्रों में से प्रत्येक को अलग-अलग फ़िल्टर करके Map<K, V> टाइप करें, और फिर इन मानचित्रों पर V1...VN मानों को सामान्य रूप से टाइप किए गए V नए मानों (यानी Function<? super Entry<K, VN>, ? extends V>) पर मानचित्रित करने के लिए 'मान मैपर' का उपयोग करें।

public static <K, VN, V> Map<K, V> filterAndMapValue(final Map<K, VN> map, 
     final Predicate<? super Entry<K, VN>> predicate, 
     final Function<? super Entry<K, VN>, ? extends V> mapper) { 
    return map.entrySet().stream().filter(predicate) 
      .collect(Collectors.toMap(Entry::getKey, mapper)); 
} 

मेरे वर्तमान उपयोग के मामलों इसे सुरक्षित माना कि केवल के बाद प्रत्येक मानचित्र पर छानने मेरे लिए अलग कुंजियां दूंगा बनाने: इस तरह के रूप में, मैं पहले दो चरणों को पूरा करने के लिए निम्न static सहायक विधि है अंतिम Map ऑब्जेक्ट (प्रत्येक मानचित्र में उपयोग की जाने वाली एक ही कुंजी हो सकती है), लेकिन उस स्थिति में जो भविष्य में सही नहीं है, मुझे पता है कि मैं इसे उचित तरीके से संभालने के लिए अभिव्यक्ति को Collectors.toMap(Function, Function, BinaryOperator) पर अभिव्यक्ति प्रदान कर सकता हूं।

अंतिम कोड अब निम्नलिखित की तरह कुछ पढ़ता है:

Map<K,V> result = filterAndMapValue(kv1, predicateForKV1, mapV1toV); 
result.putAll(filterAndMapValue(kv2, predicateForKV2, mapV2toV)); 
result.putAll(filterAndMapValue(kv2, predicateForKV3, mapV3toV)); 
... 
result.putAll(filterAndMapValue(kvN, predicateForKVN, mapVNtoV)); 
// do something with result 

प्रश्न: वहाँ ऐसा करने का एक अधिक कुशल तरीका है? यह एक अंतिम संग्रह (Map) में सामान को कम करने (फ़िल्टर किए गए मानचित्र) को कम करने के एक और मामले की तरह लगता है, जिसके लिए अलग-अलग कमी आवेषण (मूल्य मैपिंग भाग) की आवश्यकता होती है, और मुझे यकीन नहीं है कि मैं इसे सही तरीके से देख रहा हूं या नहीं।

* - यदि वे करते हैं, तो मुझे लगता है कि V1...VN माता-पिता विधि को कार्यान्वित कर सकता है, V convertToV(Object... possiblyAdditionalArgumentsToPerformTheConversion) कहें, ताकि मेरी समस्या अलग-अलग मानचित्रों के लिए फ़िल्टरिंग के विभिन्न रूपों को लागू करने के लिए कम हो। यदि इस वैकल्पिक धारणा को दिए गए एक सरल समाधान भी हैं, तो इसका भी उल्लेख करने में संकोच न करें।

+0

सभी V1 ... VN मान रखने के लिए ऑब्जेक्ट बनाने के बारे में, और केवल एक मानचित्र का उपयोग करें? – BobTheBuilder

+0

@BobThebuilder क्या आप शुरुआत में सभी मानचित्रों के मूल्य एकत्रित करने का मतलब रखते हैं? मूल्य मैपिंग अलग-अलग प्रकार के लिए अलग-अलग किया जाता है, और फिर अंत में मुझे नव निर्मित 'वी' मानों के लिए कुंजी' मैपिंग्स को भी जानने की आवश्यकता होती है ... मैंने यह भी इंगित करने के लिए एक संपादन प्रदान किया है कि 'अनन्य परिणामी कुंजी 'नक्शे पर फ़िल्टरिंग के बाद * केवल लागू है, इसलिए मूल मानचित्रों में एक ही कुंजी हो सकती है। मैं उस अर्थ में 'मानचित्र ' करने में सक्षम नहीं होगा। उम्मीद है कि यह आपके प्रश्न का उत्तर देगा। –

+0

मेरा मतलब है कि एक श्रेणी MyValues ​​बनाने के लिए जिसमें V1..VN फ़ील्ड हैं।यदि आप उस वर्ग का उपयोग करते हैं, तो माईवैल्यूज़ में एक ऑब्जेक्ट में प्रत्येक कुंजी के लिए सभी मान होते हैं और – BobTheBuilder

उत्तर

2

आप

public static <K, VN, V> Stream<Entry<K, V>> filterAndMapValue(Map<K, VN> map, 
    Predicate<? super Entry<K, VN>> predicate, 
    Function<? super Entry<K, VN>, ? extends V> mapper) { 

    return map.entrySet().stream().filter(predicate) 
       .map(e->new AbstractMap.SimpleEntry<>(e.getKey(), mapper.apply(e))); 
} 

करने के लिए अपने विधि बदलते हैं आप एक ही Stream आपरेशन की तरह के रूप में कार्रवाई करने के कर सकते हैं:

Stream.of(filterAndMapValue(kv1, predicateForKV1, mapV1toV), 
      filterAndMapValue(kv2, predicateForKV2, mapV2toV), 
      filterAndMapValue(kv3, predicateForKV3, mapV3toV), 
      …) 
     .flatMap(Function.identity()) 
     .collect(Collectors.toMap(Entry::getKey, Entry::getValue)); 

ध्यान दें कि इनपुट नक्शे की एक छोटी संख्या के लिए है, तो आप उपयोग कर सकते हैं Stream.concat लेकिन जैसे ही संख्या बढ़ती है, ऊपर दिखाया गया दृष्टिकोण बेहतर है।

मुझे एक उल्लेखनीय प्रदर्शन लाभ की उम्मीद नहीं होगी, लेकिन यह दृष्टिकोण आपकी धारणा को सत्यापित करेगा कि शेष प्रविष्टियों में कोई डुप्लिकेट कुंजी नहीं है।

+0

उत्तर के लिए धन्यवाद! –

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