2017-02-03 8 views
5

मेरे पास कोड का नीचे का टुकड़ा है।जावा 8 स्ट्रीम और लैम्बडास का उपयोग करते हुए पैरेंट तत्वों का जिक्र करते हुए लूप के लिए नेस्टेड को फिर से कैसे करें?

public static ModuleKey getDeployableModuleFromModulesList(List<Module> modules) { 
     ModuleKey deployableModuleKey = null; 
     for(Module module : modules) { 
      List<Artifact> artifacts = module.getArtifacts(); 
      for(Artifact artifact : artifacts) { 
       if(artifact.getType().equals("ear")) { 
        return module.getKey(); 
       } else if(!artifact.getType().equals("ear")) { 
        if(artifact.getType().equals("war")) { 
         deployableModuleKey = module.getKey(); 
        } 
       } 
      } 
     } 
     return deployableModuleKey; 
    } 

इस कोड कुंजी = 'कान' या कुंजी = 'युद्ध' के साथ पिछले एक के साथ पहली बार 'deployableModuleKey' पाता है। मैं जावा 8 स्ट्रीम और लैम्बडास का उपयोग कर उपर्युक्त कार्यक्षमता प्राप्त करना चाहता हूं।

अब तक मैं क्या करने की कोशिश की है:

modules.stream().flatMap(e -> e.getArtifacts().stream()) 
    .filter(e -> e.getType().equals("ear")).findFirst() 
    .orElseGet(() -> modules.stream().flatMap(e -> e.getArtifacts().stream()) 
    .filter(e -> e.getType().equals("war")).reduce((a, b) -> b).orElse(null)); 

ऊपर कोड स्निपेट प्रकार Artifact बजाय Module की एक वस्तु वापस आ जाएगी। मैं उस मॉड्यूल को प्राप्त करना चाहता हूं जहां आर्टिफैक्ट शर्तों से मेल खाता है। एक बार जब मैं मॉड्यूल पाता हूं तो मैं module.getKey() कर कर कुंजी वापस कर सकता हूं। ऐसा करने के लिए मैं जानना चाहता हूं कि हम लूप के लिए माता-पिता के तत्वों को कैसे संदर्भित करते हैं।

मुझे यकीन नहीं है कि मेरा जावा 8 कोड पूरी तरह से सही है या नहीं।
क्या कोई इस संबंध में मेरी सहायता कर सकता है?

+1

मैं आपको कुछ प्रक्रियाओं में इस प्रक्रिया को तोड़ने का सुझाव दूंगा। इसका मतलब यह नहीं है कि जावा 8 धाराओं को संचालन को बढ़ाने के लिए प्रोत्साहित नहीं किया जाता है, लेकिन जितना संभव हो सके उन्हें स्पष्ट और परमाणु बनाने के लिए। –

+0

मुझे संदेह है कि स्ट्रीम का उपयोग आपके वास्तविक कोड से बेहतर है। इंटरमीडिएट ऑपरेशंस के बीच राज्य को पकड़ने के लिए स्ट्रीम अच्छे नहीं हैं। इसके अलावा, आपका वर्तमान कोड सभी कलाकृतियों के माध्यम से एक गुजरता है, जबकि प्रस्तावित समाधान दो पास करते हैं। यदि आप केवल एक पास के साथ ऐसा करना चाहते हैं, तो मेरा सुझाव है कि आप अपना खुद का कलेक्टर बनाएं (कलेक्टर बनाने के बारे में बहुत सारे प्रश्न हैं, बस एक चुनें और वहां से जारी रखें) –

उत्तर

0

मैंने अपनी समस्या का हल निकाला है।

public static ModuleKey getDeployableModuleFromModulesList(List<Module> modules) { 
    Optional<ModuleKey> op = modules.stream().filter(module -> module.getArtifacts().stream().anyMatch(artifact -> artifact.getType().equals("ear"))).map(module -> module.getKey()).findFirst(); 
    if (!op.isPresent()) { 
     op = modules.stream().filter(module -> module.getArtifacts().stream().anyMatch(artifact -> artifact.getType().equals("war"))).map(module -> module.getKey()).reduce((a, b) -> b); 
    } 
    return op.orElse(null); 
} 

वैसे भी, अन्य समाधान भी स्वागत है। अगर कोई दूसरा समाधान जोड़ता है, तो मैं उन सभी को आजमाउंगा।

0

स्ट्रीम के साथ बात यह है कि, जब आप filter या map जैसे मध्यवर्ती ऑपरेशन का उपयोग करके अपनी स्ट्रीम संशोधित कर लेते हैं, तो आप पिछले ऑपरेशन के मानों को वापस नहीं देख सकते हैं। तो आपको हमेशा अपनी स्ट्रीम में संदर्भित करने के लिए (Module) अपने मूल्य में संदर्भित करने के लिए वर्कअराउंड ढूंढना होगा। निम्नलिखित समाधान में, मैं anyMatch संचालन के साथ दो माध्यमिक धाराएं खोलता हूं, जो मॉड्यूल में एक आर्टिफैक्ट होता है जिसमें वांछित कुंजी होती है।

इस चाल करना चाहिए:

ModuleKey key = Optional.ofNullable(modules.stream().filter(m -> m.getArtifacts().stream() 
    .anyMatch(a -> a.equals("ear"))).findFirst().orElse(modules.stream() 
    .filter(m -> m.getArtifacts().stream().anyMatch(a -> a.equals("war"))) 
    .reduce((a, b) -> b).orElse(null))).map(Module::getKey).orElse(null); 

पहला तत्व खोजने के लिए, findFirst है, जो एक Optional<T> रिटर्न का उपयोग करें। हम OptionalOptional#orElse के साथ चेन करते हैं, जो इसे अनचाहे करता है और, यदि यह खाली है, तो एक और मूल्य लौटाता है (इस मामले में अंतिम तत्व खोजने के लिए reduce((a, b) -> b) का उपयोग करके)। यदि कुछ भी नहीं मिला है, तो हम नहीं चाहते हैं कि कोड NullPointerException फेंक दें। तो इससे पहले कि हम getKey विधि को कॉल करें, हम इसे में Optional.ofNullable के साथ लपेटें और orElse से null पर सेट करें, जो आपके कोड में निर्दिष्ट डिफ़ॉल्ट मान है।

एक तरफ ध्यान दें के रूप में,

else if(!artifact.getType().equals("ear")) { 
    if(artifact.getType().equals("war")) { 
    } 
} 

else if(artifact.getType.equals("war")) { 
} 
+0

यदि मैं आपके कोड स्निपेट का उपयोग करता हूं तो मुझे निम्न संकलन त्रुटियां मिलती हैं । 'विधि फ़िल्टर (( मीटर) -> {}) प्रकार सूची 'के लिए अपरिभाषित है और' विधि getKey() प्रकार मॉड्यूल उपयोग के लिए अपरिभाषित है। 'GetKey()' विधि 'मॉड्यूल' ऑब्जेक्ट का एक हिस्सा है। –

+0

@RITZXAVI मैंने अपने सामान्य आईडीई के बजाय नोटपैड ++ में अपना कोड प्रोटोटाइप किया, और वहां एक नया ग्लिच था। मैंने उन्हें ठीक करने के लिए अपना जवाब संपादित किया, मुझे बताएं कि क्या आप अभी भी समस्याएं अनुभव कर रहे हैं। – MikaelF

+0

अब मुझे यह त्रुटि मिलती है। 'वैकल्पिक प्रकार में विधि याEsese (मॉड्यूल) तर्कों के लिए लागू नहीं है (वैकल्पिक ) ' –

0

को कम किया जा सकता मुझे लगता है कि आप जानते हैं कि आपके पुराने जावा शैली कोड में अनावश्यक if जांच।

मैंने छोटे आसान-चंचल कार्यों में तोड़कर ऑपरेशन की अपनी बड़ी एकल धारा लिखी है जिसे कोई भी समझ जाएगा।

public static ModuleKey getDeployableModuleFromModulesList(List<Module> modules) { 

    return findEARKey(modules.stream()) 
      .orElse(findWARKey(modules.stream()).orElse(null)); 

} 

public static Optional<ModuleKey> findEARKey(Stream<Module> moduleStream){ 

    return moduleStream.flatMap(e -> e.getArtifacts().stream()) 
      .filter(e -> e.getType().equals("ear")) 
      .map(Artifact::getKey).findFirst(); 
} 

public static Optional<ModuleKey> findWARKey(Stream<Module> moduleStream){ 

    return moduleStream.flatMap(e -> e.getArtifacts().stream()) 
      .filter(e -> e.getType().equals("war")) 
      .map(Artifact::getKey).findFirst(); 
} 
+0

मुझे लगता है कि अगर मैं 'तैनाती मॉड्यूलकी' टाइप = 'कान' ** या ** 'युद्ध' के साथ चाहता हूं तो मेरा कोड अच्छा है। लेकिन इसके बजाय, मैं टाइप = 'कान' के साथ पहला 'तैनाती मॉड्यूलकी' चाहता हूं। यदि 'कान' मौजूद नहीं है तो मैं टाइप = 'युद्ध' के साथ अंतिम मॉड्यूल को वापस करना चाहता हूं। –

+1

इसके अलावा, यह कोड मॉड्यूल कुंजी –

+0

की बजाय आर्टिफैक्ट कुंजी देता है हां, 'Artifact' ऑब्जेक्ट में 'कुंजी' नामक कोई विशेषता नहीं है। –

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