Подтвердить что ты не робот

Как разбить несколько циклов 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. Или если есть какой-либо другой способ рефакторинга этого кода, чтобы сделать его более читабельным и поддерживаемым. Спасибо.

4b9b3361

Ответ 1

Используйте ярлык во внешнем цикле и добавьте эту метку в оператор 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

Ответ 2

Извлеките все циклы в функцию и используйте return.

Ответ 3

Вы можете использовать выраженный оператор break. Такой разрыв прерывает внешний оператор

См. Заявление о прохождении

Ответ 4

Смотрите Ветвящиеся инструкции Java Tutorial для простейшего способа, используя метку. Вы можете пометить любые или все циклы for, а затем использовать break или continue в сочетании с этими метками.

Альтернативой использованию меток является использование return. Просто переформатируйте свой код в вызове метода, чтобы обойти необходимость использования меток вообще.

Ответ 5

Ваш пример довольно общий, поэтому трудно сказать, что происходит, но я получаю такой сильный запах кода из кода, который вы указали, что я вынужден думать, что должен быть другой способ полностью сделать это, скорее всего, путем реорганизации фактической структуры данных в нечто более значимое.

Какой список objects есть? Какие еще (наиболее важные) данные содержатся в нем? Если бы не слишком много хлопот, я был бы признателен, если бы вы предоставили более подходящий код, поскольку рефакторинг во мне становится все головокружительным, просто видя эту кучу циклов.

Ответ 6

Один из способов сломать или свернуть несколько операторов (на самом деле стоп-фреймы) - это выбросить исключение, но это не рекомендуется, потому что настало время для разматывания стека очень дорого, и это может привести к отвратительному отладке undefined поведение (помните об этом).

В противном случае, что я рекомендую, перепишите этот код, чтобы он мог вырваться из цикла грациозно. Если вы не можете изменить этот код каким-либо другим способом, то тогда вам придется привести к исключениям...

Ответ 7

Выбросить исключение и поймать его за пределами циклов? Использовать что-то, что "считается вредным?"

Это немного смешно, когда компьютерная наука рисует себя в угол; -)

Ответ 8

Простое решение состоит в том, чтобы поместить весь процесс поиска в метод и return, как только у вас появится ответ.

Однако абстрактная форма вашего образца кода оставляет некоторые другие возможности. Например, существует ли способ "проиндексировать" часть содержимого (например, с использованием экземпляров Map), чтобы вам не приходилось использовать контуры грубой силы?