J'ai quatre boucles foreach qui parcourent les collections et font quelque chose en fonction d'une condition.
Voici le code que j'écris maintenant:
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 (objets dans le code) provient d'un SDK 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 briser les quatre boucles foreach. Ou s'il existe un autre moyen de refactoriser ce code pour le rendre plus lisible et maintenable.
Utilisez une étiquette sur la boucle la plus externe et incluez cette étiquette dans l'instruction break
lorsque vous voulez sauter hors 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
Extrayez toutes les boucles dans la fonction et utilisez return.
Vous pouvez utiliser une instruction break étiquetée. Ce type de pause met fin à une instruction externe
Voir La déclaration break
Voir le Instructions de branchement Java Tutorial pour la manière la plus simple, en utilisant une étiquette. Vous pouvez étiqueter une ou toutes les boucles for, puis utiliser break
ou continue
en conjonction avec ces étiquettes.
Une alternative à l'utilisation d'étiquettes consiste à utiliser return
à la place. Refactorisez simplement votre code en un appel de méthode pour contourner le besoin d'utiliser des étiquettes.
Votre exemple est plutôt générique, il est donc difficile de dire ce qui se passe, mais le code que vous avez fourni me donne une telle odeur de code que je suis obligé de penser qu'il doit y avoir un autre moyen de faire la chose entièrement, très probablement par refactoriser la structure de données réelle en quelque chose de plus significatif.
Quel genre de liste objects
est-il? Quelles autres données (très probablement importantes) qu'il contient? Si ce n'est pas trop compliqué, j'apprécierais si vous fournissiez un code plus pertinent car le refactoreur en moi devient tout étourdi juste en voyant cette pile de boucles.
Une façon de casser ou de réduire plusieurs instructions (en fait, empiler des cadres) est de lancer une exception, mais ce n'est pas recommandé car il est très coûteux pour l'exécution de dérouler la pile et cela pourrait conduire à un comportement vraiment difficile à déboguer, (Garde ça en tête).
Sinon, ce que je recommande, réécrivez ce code pour pouvoir sortir de la boucle de manière gracieuse. Si vous ne pouvez pas changer ce code d'une autre manière, eh bien, vous devrez entraîner des exceptions ...
Lancer une exception et l'attraper en dehors des boucles? Utilisez quelque chose qui est "considéré comme dangereux"?
C'est un peu drôle quand l'informatique se peint dans un coin ;-)
La solution la plus simple consiste à placer l'ensemble du processus de recherche dans une méthode et return
dès que vous avez une réponse.
Cependant, la forme abstraite de votre exemple de code laisse d'autres possibilités en question. Par exemple, existe-t-il un moyen d '"indexer" une partie du contenu (par exemple en utilisant des instances Map
) afin de ne pas avoir à utiliser des boucles de force brute?
Outre le fait que Java prend en charge la rupture étiquetée, voir aussi Est-il possible de quitter un for before time en C++, si une condition de fin est atteinte? qui est un question similaire avec d'autres solutions pertinentes.