Rompendo loops aninhados

Rompendo loops aninhados

1. Visão geral

Neste tutorial, criaremos alguns exemplos para mostrar diferentes maneiras de usarbreak em um loop. A seguir, também veremos como encerrar um loop sem usar break.

2. O problema

Loops aninhados são muito úteis, por exemplo, para pesquisar em uma lista de listas.

Um exemplo seria uma lista de alunos, onde cada aluno tem uma lista de cursos planejados. Digamos que queremos encontrar o nome de uma pessoa que planejoucourse 0.

Primeiro, veríamos a lista de alunos. Então, dentro desse loop, repetiríamos a lista de cursos planejados.

Quando imprimimos os nomes dos alunos e cursos, obteremos o seguinte resultado:

student 0
  course 0
  course 1
student 1
  course 0
  course 1

Queríamos encontrar o primeiro aluno que planejoucourse 0. No entanto, se apenas usarmos loops, o aplicativo continuará pesquisando depois que o curso for encontrado.

Depois de encontrarmos uma pessoa que planejou o curso específico,we want to stop searching. Continuar a pesquisar levaria mais tempo e recursos, enquanto não precisamos de informações extras. That’s why we want to break fora do loop aninhado.

3. Pausa

A primeira opção que temos para sair de um loop aninhado é simplesmente usar a instruçãobreak:

String result = "";
for (int outerCounter = 0; outerCounter < 2; outerCounter++) {
    result += "outer" + outerCounter;
    for (int innerCounter = 0; innerCounter < 2; innerCounter++) {
        result += "inner" + innerCounter;
        if (innerCounter == 0) {
            break;
        }
    }
}
return result;

Temos um loop externo e um loop interno, ambos os loops têm duas iterações. Se o contador do loop interno for igual a 0, executamos o comandobreak. Quando executamos o exemplo, ele mostrará o seguinte resultado:

outer0inner0outer1inner0

Ou podemos ajustar o código para torná-lo um pouco mais legível:

outer 0
  inner 0
outer 1
  inner 0

É isso que nós queremos?

Quase,the inner loop is terminated by the break statementafter 0 is found. However, the outer loop continues, que não é o que queremos. Queremos parar completamente o processamento assim que tivermos a resposta.

4. Ruptura rotulada

O exemplo anterior foi um passo na direção certa, mas precisamos melhorá-lo um pouco. Podemos fazer isso usando umlabeled break:

String result = "";
myBreakLabel:
for (int outerCounter = 0; outerCounter < 2; outerCounter++) {
    result += "outer" + outerCounter;
    for (int innerCounter = 0; innerCounter < 2; innerCounter++) {
        result += "inner" + innerCounter;
        if (innerCounter == 0) {
            break myBreakLabel;
        }
    }
}
return result;

A labeled break will terminate the outer loop instead of just the inner loop. Conseguimos isso adicionandomyBreakLabel fora do loop e alterando a instrução break para pararmyBreakLabel. Depois de executar o exemplo, obtemos o seguinte resultado:

outer0inner0

Podemos ler um pouco melhor com algumas formatações:

outer 0
  inner 0

Se olharmos para o resultado, podemos ver queboth the inner loop and the outer loop are terminated, que é o que queríamos alcançar.

5. Retorna

Como alternativa, também podemos usar a instruçãoreturn para retornar diretamente o resultado quando for encontrado:

String result = "";
for (int outerCounter = 0; outerCounter < 2; outerCounter++) {
    result += "outer" + outerCounter;
    for (int innerCounter = 0; innerCounter < 2; innerCounter++) {
        result += "inner" + innerCounter;
        if (innerCounter == 0) {
            return result;
        }
    }
}
return "failed";

O rótulo é removido e a instruçãobreak é substituída por uma instruçãoreturn.

When we execute the code above we get the same result as for the labeled break.  Observe que, para essa estratégia funcionar, normalmente precisamos mover o bloco de loops em seu próprio método.

6. Conclusão

Então, acabamos de ver o que fazer quando precisamos sair mais cedo de um loop, como quando encontramos o item que procuramos. A palavra-chavebreak é útil para loops únicos, e podemos usarbreaks rotulados para loops aninhados.

Alternatively, we can use a return statement. Usar return torna o código mais legível e menos sujeito a erros, pois não temos que pensar sobre a diferença entre quebras não rotuladas e rotuladas.

Sinta-se à vontade para dar uma olhada no códigoover on GitHub.