java - जावा में नेस्टेड छोरों से बाहर तोड़ना




loops (20)

(संपादित करें: अन्य answerers की तरह, मैं निश्चित रूप से एक अलग विधि में आंतरिक पाश डाल पसंद करेंगे । यह जवाब सिर्फ दिखाता है कि प्रश्न में आवश्यकताओं को कैसे पूरा किया जा सकता है।)

आप बाहरी लूप के लिए एक लेबल के साथ break उपयोग कर सकते हैं। उदाहरण के लिए:

public class Test {
  public static void main(String[] args) {
    outerloop:
    for (int i=0; i < 5; i++) {
      for (int j=0; j < 5; j++) {
        if (i * j > 6) {
          System.out.println("Breaking");
          break outerloop;
        }
        System.out.println(i + " " + j);
      }
    }
    System.out.println("Done");
  }
}

यह प्रिंट करता है:

0 0
0 1
0 2
0 3
0 4
1 0
1 1
1 2
1 3
1 4
2 0
2 1
2 2
2 3
Breaking
Done

मुझे नेस्टेड लूप इस तरह से निर्माण किया गया है:

for (Type type : types) {
    for (Type t : types2) {
         if (some condition) {
             // Do something and break...
             break; // Breaks out of the inner loop
         }
    }
}

अब मैं दोनों लूपों से कैसे बाहर तोड़ सकता हूं मैंने इसी तरह के प्रश्नों को देखा है, लेकिन कोई विशेष रूप से जावा से कोई चिंता नहीं करता मैं इन समाधानों को लागू नहीं कर सका क्योंकि अधिकतर उपयोग किए गए पास।

मैं एक अलग विधि में भीतरी लूप को नहीं डालना चाहता हूँ।

अद्यतन: मैं लूप को फिर से चलाने के लिए नहीं चाहता, जब ब्रेक के निष्पादन के साथ समाप्त हो रहा है I


@ 1800 सूचना सुझाव की तरह, बाहरी लूप पर एक शर्त के रूप में आंतरिक पाश को तोड़ने वाली स्थिति का उपयोग करें:

boolean hasAccess = false;
for (int i = 0; i < x && hasAccess == false; i++){
  for (int j = 0; j < y; j++){
    if (condition == true){
      hasAccess = true;
      break;
    }
  }
}

आप एक अस्थायी चर का उपयोग कर सकते हैं:

boolean outerBreak = false;
for (Type type : types) {
   if(outerBreak) break;
    for (Type t : types2) {
         if (some condition) {
             // Do something and break...
             outerBreak = true;
             break; // Breaks out of the inner loop
         }
    }
}

आपके फ़ंक्शन के आधार पर, आप भीतरी लूप से बाहर निकल सकते हैं / लौट सकते हैं:

for (Type type : types) {
    for (Type t : types2) {
         if (some condition) {
             // Do something and break...
             return;
         }
    }
}

आप एक काम कर सकते हैं

1.) एक स्थानीय चर को गलत सेट करें

2.) उस चर को पहले लूप में सही सेट करें, जब आप इसे तोड़ना चाहते हैं

3.) तो आप बाहरी लूप में जांच कर सकते हैं, कि क्या स्थिति सेट है तो बाहरी लूप से भी टूट जाती है।

boolean isBreakNeeded = false;
for (int i = 0; i < some.length; i++) {
    for (int j = 0; j < some.lengthasWell; j++) {
        //want to set variable if (){
        isBreakNeeded = true;
        break;
    }

    if (isBreakNeeded) {
        break; //will make you break from the outer loop as well
    }
}

खैर, यह मेरे लिए यह पसंद करने के लिए एक आसान तरीका था।


आप लूप के आसपास एक नामित ब्लॉक का उपयोग कर सकते हैं:

search: {
    for (Type type : types) {
        for (Type t : types2) {
            if (some condition) {
                // Do something and break...
                break search;
            }
        }
    }
}

आप लेबल का उपयोग कर सकते हैं:

label1: 
    for (int i = 0;;) {
        for (int g = 0;;) {
          break label1;
        }
    }

उदाहरण के बिना उल्लिखित एक अन्य समाधान, (यह वास्तव में कोड कोड में काम करता है)।

try {
    for (Type type : types) {
        for (Type t : types2) {
            if (some condition #1) {
                // Do something and break the loop.
                throw new BreakLoopException();
            }
        }
    }
}
catch (BreakLoopException e) {
    // Do something on look breaking.
}

बेशक ब्रेक अपवाद आंतरिक, निजी और बिना स्टैक-ट्रेस के साथ त्वरित होना चाहिए:

private static class BreakLoopException extends Exception {
    @Override
    public StackTraceElement[] getStackTrace() {
        return new StackTraceElement[0];
    }
}

एक लंबे समय के लिए मैं इस प्रकार के प्रश्न के लिए इस प्रकार के उत्तर को साझा करने की सोच रहा था।

आम तौर पर ऐसे मामलों में एक अधिक अर्थपूर्ण तर्क के दायरे आते हैं, आइए हम कुछ विचित्र 'for'- वस्तुओं के प्रश्नों पर कुछ खोज या जोड़ तोड़ देते हैं, इसलिए मैं आमतौर पर कार्यात्मक दृष्टिकोण का उपयोग करता हूं:

public Object searching(Object[] types) {//or manipulating
    List<Object> typesReferences = new ArrayList<Object>();
    List<Object> typesReferences2 = new ArrayList<Object>();

    for (Object type : typesReferences) {
        Object o = getByCriterion(typesReferences2, type);
        if(o != null) return o; 
    }
    return null;
}
private Object getByCriterion(List<Object> typesReferences2, Object criterion) {
    for (Object typeReference : typesReferences2) {
        if(typeReference.equals(criterion)) {
             // here comes other complex or specific logic || typeReference.equals(new Object())
             return typeReference;
        }
    }
    return null;
}

मुख्य विपक्ष:

  • मोटे तौर पर दो बार अधिक लाइनें
  • कंप्यूटिंग चक्रों की अधिक खपत, जिसका अर्थ यह एल्गोरिथम बिंदु-व्यू से धीमी है
  • अधिक टाइपिंग कार्य

गुण:

  • कार्यात्मक ग्रैन्युलैरिटी के कारण चिंताओं को अलग करने के लिए उच्च अनुपात
  • फिर से प्रयोज्यता के उच्च अनुपात और बिना खोज / जोड़ तोड़ तर्क के नियंत्रण
  • तरीकों लंबी नहीं हैं, इस प्रकार वे अधिक कॉम्पैक्ट और समझना आसान है
  • पठनीयता का आंशिक उच्च अनुपात

तो यह सिर्फ एक अलग दृष्टिकोण के जरिये मामले को संभाल रहा है

मूल रूप से इस प्रश्न के लेखक को एक प्रश्न: आप इस दृष्टिकोण के बारे में क्या सोचते हैं?


जांचें कि आंतरिक लूप एक बयान के साथ बाहर निकलता है, तो आंतरिक पाश के चर को चेक करके। आप एक और चर भी बना सकते हैं जैसे कि बुलियन को देखने के लिए कि आंतरिक लूप निकल गया है या नहीं।

इस उदाहरण में यह जांचने के लिए आंतरिक लूप के चर का उपयोग करता है कि क्या इसे बाहर किया गया है:

int i, j;
for(i = 0; i < 7; i++){

for(j = 0; j < 5; j++) {

     if (some condition) {
         // Do something and break...
         break; // Breaks out of the inner loop
     }
}
     if(j < 5){    // Checks if inner loop wasn't finished
     break;    // Breaks out of the outer loop   
     } 
}

जावा 8 स्ट्रीम समाधान:

List<Type> types1 = ...
List<Type> types2 = ...

types1.stream()
      .flatMap(type1 -> types2.stream().map(type2 -> new Type[]{type1, type2}))
      .filter(types -> /**some condition**/)
      .findFirst()
      .ifPresent(types -> /**do something**/);

बल्कि असामान्य दृष्टिकोण पर कोड लंबाई ( प्रदर्शन नहीं ) के संदर्भ में यह सबसे आसान काम है जो आप कर सकते हैं:

for(int i=0; i++; i<j){
    if(wanna exit){
        i=i+j; //if more nested, also add the 
               //maximum value for the other loops
    }
}

मुझे ऐसा करने की जरूरत थी, लेकिन मैंने इसे करने के लिए पाश के लिए बढ़ाया उपयोग नहीं किया।

int s = type.size();
for (int i = 0; i < s; i++) {
    for (int j = 0; j < t.size(); j++) {
        if (condition) {
            // do stuff after which you want 
            // to completely break out of both loops
            s = 0; // enables the _main_ loop to terminate
            break;
        }
    }
}

मैं this सवाल का जवाब देना चाहता था लेकिन एक डुप्लिकेट के रूप में चिह्नित किया गया था जो मुझे पोस्टिंग से भी रोकता है। तो इसके बजाय यहां पोस्टिंग!

यदि इसका एक नया कार्यान्वयन आप तर्क-पुनः लिखने की कोशिश कर सकते हैं जैसे- else_if-else बयान

while(keep_going) {

    if(keep_going && condition_one_holds) {
        // code
    }
    if(keep_going && condition_two_holds) {
        // code
    }
    if(keep_going && condition_three_holds) {
        // code
    }
    if(keep_going && something_goes_really_bad) {
        keep_going=false;
    }
    if(keep_going && condition_four_holds) {
        // code
    }
    if(keep_going && condition_five_holds) {
        // code
    }   
}

अन्यथा आप झंडा निर्धारित करने की कोशिश कर सकते हैं जब यह विशेष स्थिति आती है और आपके प्रत्येक लूप-स्थितियों में उस ध्वज के लिए जांच कर सकते हैं।

something_bad_has_happened = false;
while(something is true && !something_bad_has_happened){
    // code, things happen
    while(something else && !something_bad_has_happened){
        // lots of code, things happens
        if(something happened){
            -> Then control should be returned ->
            something_bad_has_happened=true;
            continue;
        }
    }   
    if(something_bad_has_happened) { // things below will not be executed
        continue;
    }

    // other things may happen here as well but will not be executed
    //  once control is returned from the inner cycle
}

HERE! So, while a simple break will not work, it can be made to work using continue.

यदि आप बस तर्क को एक प्रोग्रामिंग भाषा से जावा तक को पोर्ट कर रहे हैं और सिर्फ काम करने के लिए काम करना चाहते हैं, तो आप labels का उपयोग करने की कोशिश कर सकते labels


मैं पाश परीक्षणों में एक स्पष्ट "निकास" जोड़ना पसंद करता हूं यह किसी भी आकस्मिक पाठक को स्पष्ट करता है कि लूप प्रारंभिक रूप से समाप्त हो सकता है

boolean earlyExit = false;
for(int i=0;i<10&&!earlyExit; i++) {
 for(int j=0;i<10&&!earlyExit; j++) { earlyExit=true; }
}

यदि आपको break और goto पसंद नहीं है, तो आप इसके अतिरिक्त ऐप के लिए एक "पारंपरिक" पाश का उपयोग कर सकते हैं, एक अतिरिक्त गर्भपात की स्थिति के साथ:

int a, b;
bool abort = false;
for (a = 0; a < 10 && !abort; a++) {
    for (b = 0; b < 10 && !abort; b++) {
        if (condition) {
            doSomeThing();
            abort = true;
        }
    }
}

यदि यह कुछ फ़ंक्शन के अंदर है तो आप इसे वापस क्यों नहीं करते हैं:

for (Type type : types) {
    for (Type t : types2) {
         if (some condition) {
            return value;
         }
    }
}


शायद एक समारोह के साथ?

public void doSomething(List<Type> types, List<Type> types2){
  for(Type t1 : types){
    for (Type t : types2) {
      if (some condition) {
         //do something and return...
         return;
      }
    }
  }
}

for (int j = 0; j < 5; j++) //inner loop साथ प्रतिस्थापित किया जाना चाहिए for (int j = 0; j < 5 && !exitloops; j++)

यहां, इस स्थिति में पूर्ण नीडिंत loops को बाहर होना चाहिए अगर हालत True लेकिन अगर हम केवल ऊपरी loop लिए बाहर exitloops उपयोग करते हैं

 for (int i = 0; i < 5 && !exitloops; i++) //upper loop

फिर भीतरी लूप जारी रहेगा, क्योंकि कोई अतिरिक्त ध्वज नहीं है जो इस आंतरिक पाश को बाहर निकलने के लिए सूचित करता है

उदाहरण: यदि i = 3 और j=2 तो स्थिति false । लेकिन अगले लूप j=3 अगले पुनरावृत्त में तब स्थिति (i*j) 9 हो जाती है जो कि true लेकिन जब तक 5 बनने तक आंतरिक पाश जारी रहेगा।

इसलिए, इसे भीतरी लूपों में भी बाहर exitloops का उपयोग करना चाहिए।

    boolean exitloops= false;
    for (int i = 0; i < 5 && !exitloops; i++) { //here should exitloops as a Conditional Statement to get out from the loops if exitloops become true. 
        for (int j = 0; j < 5 && !exitloops; j++) { //here should also use exitloops as a Conditional Statement. 
            if (i * j > 6) {
                exitloops = true;
                System.out.println("Inner loop still Continues For i * j is => "+i*j);
                break;
            }
            System.out.println(i*j);
        }
    }

boolean broken = false; // declared outside of the loop for efficiency
for (Type type : types) {
    for (Type t : types2) {
        if (some condition) {
            broken = true;
            break;
        }
    }

    if (broken) {
        break;
    }
}




loops