33 votes

Comment casser plusieurs boucles foreach ?

J'ai quatre boucles foreach qui parcourent les collections et, en fonction d'une condition, font quelque chose.

Voici le code que j'écris actuellement :

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

L'objet principal (les objets dans le code) provient d'un SDK d'un fournisseur tiers, je ne peux donc rien changer sur cette partie. Je veux demander à la communauté Stack Overflow s'il existe une meilleure approche pour casser les quatre boucles foreach. Ou s'il existe un autre moyen de remanier ce code pour le rendre plus lisible et plus facile à maintenir.

0 votes

Btw, c'est pour pas foreach .

3 votes

Non, la boucle for(Object o : os) est en fait connue sous le nom de foreach ou iterator.

0 votes

La version originale avait "foreach" dans le code lui-même. Merci pour l'édition.

80voto

Luke Woodward Points 20417

Utilisez une étiquette sur la boucle la plus extérieure, et incluez cette étiquette dans le fichier break lorsque vous voulez sortir de toutes les boucles. Dans l'exemple ci-dessous, j'ai modifié votre code pour utiliser l'étiquette 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

4 votes

C'est la réponse correcte à ma question. Mais j'ai remanié comme d'autres personnes l'ont suggéré et j'ai déplacé la logique dans une petite fonction et utilisé "return".

0 votes

N'utilisez les fonctions d'étiquetage que si vous n'avez pas d'autre solution. Ce n'est pas une bonne pratique.

20voto

Alex Reitbort Points 9120

Extraire toutes les boucles dans la fonction et utiliser return.

0 votes

Le code tel qu'il est présenté n'est pas beau : une refactorisation dans ce sens serait bien meilleure.

2 votes

Cette méthode est préférable à l'utilisation des étiquettes break, sauf si vous savez qu'il est plus clair d'utiliser break.

0 votes

Introduire une limite de méthode à un endroit arbitraire est "la méthode préférée" ?

6voto

Pierre Points 15256

Vous pouvez utiliser une instruction de rupture étiquetée. Ce type de rupture met fin à une instruction externe

Ver La déclaration de rupture

2voto

Bill the Lizard Points 147311

Voir le Instructions de branchement Tutoriel Java pour la manière la plus simple, en utilisant une étiquette. Vous pouvez étiqueter une ou toutes les boucles for, puis utiliser la commande break o continue en conjonction avec ces étiquettes.

Une alternative à l'utilisation d'étiquettes est d'utiliser return à la place. Il suffit de refactoriser votre code en un appel de méthode pour éviter d'avoir à utiliser des étiquettes.

2voto

Esko Points 15578

Votre exemple est plutôt générique, il est donc difficile de dire ce qui se passe, mais je ressens une telle odeur de code dans le code que vous avez fourni que je suis obligé de penser qu'il doit y avoir une autre façon de faire les choses, très probablement en remaniant la structure de données actuelle vers quelque chose de plus significatif.

Quel genre de liste objects est ? Quels autres (très probablement important) données qu'il contient ? Si ce n'est pas trop compliqué, j'apprécierais que vous fournissiez un code plus pertinent, car le refactor en moi devient tout étourdi rien qu'en voyant cette pile de boucles.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X