2009-02-15 491 views
29

我有四個foreach循環遍歷集合並根據條件做一些事情。下面是我現在寫代碼:如何打破多個foreach循環?

boolean breakFlag = false; 
String valueFromObj2 = null; 
String valueFromObj4 = null; 
for(Object1 object1: objects){ 
    for(Object2 object2: object1){ 
    //I get some value from object2 
    valueFromObj2 = object2.getSomeValue(); 
    for(Object3 object3 : object2){ 
     for(Object4 object4: object3){ 
     //Finally I get some value from Object4. 
     valueFromObj4 = object4.getSomeValue(); 
     //Compare with valueFromObj2 to decide either to break all the foreach loop 
     breakFlag = compareTwoVariable(valueFromObj2, valueFromObj4); 
     if(breakFlag){break;} 
     }//fourth loop ends here 
     if(breakFlag){break;} 
    }//third loop ends here 
    if(breakFlag){break;} 
    }//second loop ends here 
    if(breakFlag){break;} 
}//first loop ends here 

主要對象(代碼中的對象)來自第三方供應商的SDK,所以我不能改變的那部分東西。我想問問stackoverflow社區是否有更好的方法來打破所有四個foreach循環。或者,如果有任何其他方式來重構此代碼,使其更具可讀性和可維護性。謝謝。

+0

順便說一句,它是* for * not * foreach *。 – 2009-02-15 21:12:31

+3

不,for(Object o:os)實際上被稱爲foreach或迭代器循環。 – Esko 2009-02-16 06:52:29

+0

原始版本在代碼中有「foreach」。感謝您的編輯。 – royalGhost 2009-02-16 14:28:32

回答

78

在最外面的循環中使用標籤,並且當您想跳出所有循環時,在break語句中包含此標籤。在下面的示例中,我修改了代碼以使用標籤OUTERMOST

String valueFromObj2 = null; 
String valueFromObj4 = null; 
OUTERMOST: for(Object1 object1: objects){ 
    for(Object2 object2: object1){ 
    //I get some value from object2 
    valueFromObj2 = object2.getSomeValue(); 
    for(Object3 object3 : object2){ 
     for(Object4 object4: object3){ 
     //Finally I get some value from Object4. 
     valueFromObj4 = object4.getSomeValue(); 
     //Compare with valueFromObj2 to decide either to break all the foreach loop 
     if(compareTwoVariable(valueFromObj2, valueFromObj4)) { 
      break OUTERMOST; 
     } 
     }//fourth loop ends here 
    }//third loop ends here 
    }//second loop ends here 
}//first loop ends here 
0

拋出異常並將其捕獲到循環之外?使用「被認爲有害的東西?」

這是一個有點滑稽,當計算機科學描繪自己變成一個角落;-)打破,或摺疊幾個語句(實際上堆棧幀)

+3

「計算機科學」並沒有「將自己描繪成一個角落」。但有時程序員會做出早期的選擇或假設,以後再限制他們的選擇。 – 2009-02-15 21:11:08

+2

我覺得我很有趣。結果可能不同。 – dwc 2009-02-15 21:18:30

1

一種方法是拋出一個異常,但不建議這樣做,因爲它真的昂貴的運行時間來解開堆棧,並且它可能會導致非常難以調試未定義的行爲,(記住這一點)。

否則,我建議,重寫代碼以便能夠以優雅的方式跳出循環。如果您不能以其他方式更改此代碼,那麼您將不得不導致異常...

19

將所有循環提取到函數中並使用return。

0

的簡單的解決辦法是儘快把整個搜索過程中的方法和return,你有一個答案。

但是,示例代碼的抽象形式留下了一些其他可能的問題。例如,有沒有辦法「索引」一些內容(例如使用Map實例),以便您不必使用強力循環?

2

查看Branching Statements Java Tutorial最簡單的方法,使用標籤。您可以標記任何或所有for循環,然後將breakcontinue與這些標籤結合使用。

使用標籤的替代方法是使用return代替。只需將代碼重構成方法調用即可繞過使用標籤的需要。

2

你的例子是相當通用的,所以很難說出發生了什麼,但是我從你提供的代碼中獲得瞭如此強大的代碼氣味,我不得不認爲必須有另一種方式來完成這件事,最有可能的是通過重構實際的數據結構到更有意義的東西。

什麼樣的清單objects是?其他(最有可能重要)它包含的數據?如果它不是太麻煩,我會很感激,如果你提供了更相關的代碼,因爲從我看到的那堆循環中,重構者正在變得所有的頭腦發熱。