tutorial - java verify




स्ट्रीम में जावा 8 फ़ॉरच लूप का उपयोग करके अगले आइटम पर जाएं (3)

मुझे जावा 8 की धारा के साथ एक समस्या है जो कि लूप में अगले आइटम पर जाने की कोशिश कर रही है। मैं आदेश continue; नहीं continue; , केवल return; काम करता है लेकिन आप इस मामले में लूप से बाहर निकल जाएंगे। मुझे लूप में अगले आइटम पर जाने की आवश्यकता है। मैं उसे कैसे कर सकता हूँ?

उदाहरण (काम नहीं):

try(Stream<String> lines = Files.lines(path, StandardCharsets.ISO_8859_1)){
            filteredLines = lines.filter(...).foreach(line -> {
           ...
           if(...)
              continue; // this command doesn't working here
    });
}

उदाहरण (कार्य):

try(Stream<String> lines = Files.lines(path, StandardCharsets.ISO_8859_1)){
    filteredLines = lines.filter(...).collect(Collectors.toList());
}

for(String filteredLine : filteredLines){
   ...
   if(...)
      continue; // it's working!
}

आप forEach() को पास कर रहे हैं, वह स्ट्रीम से प्राप्त प्रत्येक तत्व के लिए मूल्यांकन किया गया है। लेम्बडा के दायरे के भीतर से पुनरावृति स्वयं दिखाई नहीं देती है, इसलिए आप इसे continue नहीं continue सकते हैं जैसे कि forEach() एक C प्रीप्रोसेसर मैक्रो थे। इसके बजाय, आप सशर्त रूप से इसमें दिए गए शेष कथनों को छोड़ सकते हैं।


एक अन्य समाधान: अपने उल्टे स्थितियों के साथ एक फिल्टर के माध्यम से जाना: उदाहरण:

if(subscribtion.isOnce() && subscribtion.isCalled()){
                continue;
}

से बदला जा सकता है

.filter(s -> !(s.isOnce() && s.isCalled()))

सबसे सीधा दृष्टिकोण "वापसी" का उपयोग करते हुए प्रतीत होता है हालांकि।


return; का उपयोग करना return; ठीक काम करेगा। यह पूर्ण लूप को पूरा करने से नहीं रोकेगा। यह केवल forEach लूप के वर्तमान पुनरावृत्ति को निष्पादित करना बंद कर देगा।

निम्नलिखित छोटे कार्यक्रम का प्रयास करें:

public static void main(String[] args) {
    ArrayList<String> stringList = new ArrayList<>();
    stringList.add("a");
    stringList.add("b");
    stringList.add("c");

    stringList.stream().forEach(str -> {
        if (str.equals("b")) return; // only skips this iteration.

        System.out.println(str);
    });
}

आउटपुट:


सी

नोटिस कैसे return; b पुनरावृति के लिए निष्पादित किया जाता है, लेकिन निम्नलिखित पुनरावृत्ति पर c ठीक प्रिंट करता है।

यह काम क्यों करता है?

पहली बार में व्यवहार अनुचित लगने का कारण यह है क्योंकि हम पूरे विधि के निष्पादन को बाधित करने वाले return स्टेटमेंट के लिए उपयोग किए जाते हैं। तो इस मामले में, हम उम्मीद करते हैं कि main विधि का निष्पादन एक पूरे के रूप में किया जाएगा।

हालांकि, समझने की जरूरत है कि एक लंबोदर अभिव्यक्ति, जैसे:

str -> {
    if (str.equals("b")) return;

    System.out.println(str);
}

... वास्तव में इसे अपनी अलग "पद्धति" के रूप में माना जाना चाहिए, main विधि से पूरी तरह से अलग होने के बावजूद, इसके भीतर आसानी से स्थित होने के बावजूद। तो वास्तव में, return कथन केवल लंबोदर अभिव्यक्ति के निष्पादन को रोक देता है।

दूसरी बात जिसे समझने की आवश्यकता है, वह है:

stringList.stream().forEach()

... वास्तव में कवर के नीचे एक सामान्य लूप है जो हर पुनरावृत्ति के लिए लंबोदर अभिव्यक्ति को निष्पादित करता है।

इन 2 बिंदुओं को ध्यान में रखते हुए, उपरोक्त कोड को निम्नलिखित समकक्ष तरीके से (केवल शैक्षिक उद्देश्यों के लिए) फिर से लिखा जा सकता है:

public static void main(String[] args) {
    ArrayList<String> stringList = new ArrayList<>();
    stringList.add("a");
    stringList.add("b");
    stringList.add("c");

    for(String s : stringList) {
        lambdaExpressionEquivalent(s);
    }
}

private static void lambdaExpressionEquivalent(String str) {
    if (str.equals("b")) {
        return;
    }

    System.out.println(str);
}

इस "कम जादू" कोड के साथ, return स्टेटमेंट का दायरा अधिक स्पष्ट हो जाता है।





java