2015-03-20 7 views
5

मैं if और else बयान है कि lambdas में विभिन्न कार्यों, को नेतृत्व और धाराओं के साथ जटिल तार्किक स्थिति का अनुवाद करने के लिए एक साफ रास्ता तलाश कर रहा हूँ अंदर अनुवाद जटिल सशर्त तर्क।नदियों और lambdas में एक पाश

मान लीजिए मैं इस कोड है:

List<OuterData> result = new LinkedList<>(); 

for (Outer outer : getOutersFromSomewhere()) { 
    OuterData outerData = new OuterData(); 

    if (outer.isImportant()) { 
     doImportantAction(outer, outerData); 
    } else if (outer.isTrivial()) { 
     doTrivialAction(outer, outerData); 
    } else { 
     doDefaultAction(outer, outerData); 
    } 

    for (Inner inner : outer.getInners()) { 
     if (inner.mustBeIncluded()) { 
      InnerData innerData = new InnerData(); 

      if (inner.meetsCondition1()) { 
       doAction1(inner, innerData, outer, outerData); 
      } else if (inner.meetsCondition2()) { 
       doAction2(inner, innerData, outer, outerData); 
      } else { 
       doDefaultAction(inner, innerData, outer, outerData); 
      } 
      outerData.add(innerData); 
     } 
    } 
    result.add(outerData); 
} 

return result; 

यह वास्तविक कोड मेरे पास से सरल है। मुझे पता है कि इसे अनुकूलित और रिफैक्टर किया जा सकता है, यानी मैं आंतरिक for को private विधि में ले जा सकता हूं। मैं जानना चाहता हूं कि if, else if और else भागों को स्ट्रीम और लैम्बडास का अनुवाद कैसे करना है।

मुझे पता है कि इस उदाहरण के कंकाल का अनुवाद कैसे करें। मैं List.stream(), Stream.map(), Stream.filter(), Stream.collect() और Stream.peek() का उपयोग करता हूं। मेरी समस्या केवल सशर्त शाखाओं के साथ है। मैं यह अनुवाद कैसे कर सकता हूं?

+2

हो सकता है कि आप अपने उदाहरण में कोड को सरल बना सकें। –

+0

@ राउलगुई ओके मैं ऐसा करूँगा। धन्यवाद –

+1

मुझे लगता है कि यदि आप सशर्त और कुछ के शरीर के साथ एक foreach के साथ कुछ अलग फिल्टर का उपयोग कर सकते हैं। –

उत्तर

5

एक पहला स्पष्ट तरीका है अपने तत्वों को स्ट्रीम करना, आवश्यक मानदंडों के अनुसार उन्हें फ़िल्टर करना, और उसके बाद प्रत्येक शेष तत्व पर कार्रवाई लागू करना। यह भी अधिक स्वच्छ कोड बनाता है:

List<Outer> outers = getOutersFromSomewhere(); 
outers.stream().filter(Outer::isImportant) 
    .forEach(outer -> doImportantAction(outer, outerDate)); 
outers.stream().filter(Outer::isTrivial) 
    .forEach(outer -> doTrivialAction(outer, outerDate)); 
// default action analog 

सावधानी: यह केवल काम करता है अगर, महत्वपूर्ण तुच्छ, और डिफ़ॉल्ट तत्वों एक विभाजन के रूप में। अन्यथा यह आपके if-else-struct के बराबर नहीं है। लेकिन शायद यह वांछित है ...

इस दृष्टिकोण के साथ मुख्य समस्या: यह बहुत अच्छा ओओपी नहीं है। निर्णय लेने के लिए आप वस्तुओं से पूछताछ कर रहे हैं। लेकिन ओओपी जितना संभव हो सके "बताओ, मत पूछो" होना चाहिए।

public class Outer { 
    ... 
    public void act(OuterData data, Consumer<Outer> importantAction, 
      Consumer<Outer> trivialAction, Consumer<Outer> defaultAction) { 
     if (isImportant()) 
      importantAction.accept(this, data); 
     else if (isTrivial()) 
      trivialAction.accept(this, data); 
     else 
      defaultAction.accept(this, data); 
    } 
} 

अब आप इसे इस रूप में सरल फोन:

तो एक और समाधान अपने Outer कक्षा में एक लेने वाली विधि प्रदान करना है

List<Outer> outers = getOutersFromSomewhere(); 
outers.forEach(outer -> outer.act(...)); // place consumers here (lambdas) 

यह एक स्पष्ट लाभ है: आप अगर कभी अपने Outer कक्षा में एक सुविधा जोड़नी है - मान लें कि isComplex() - आपको केवल उस एकल वर्ग के आंतरिक को बदलना होगा (और शायद अन्य भागों में कंपाइलर विफलता को हल करना होगा)। या माई आप इस सुविधा को पिछड़े संगत तरीके से जोड़ सकते हैं।

उसी नियम को Inner कक्षा और पुनरावृत्ति पर लागू किया जा सकता है।

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