Quando você não tem um contador
O loop for é construído em torno de um contador que você define de antemão. Mas muitos loops não têm uma contagem clara: continuar lendo linhas até o arquivo terminar, continuar pedindo uma senha até ela estar correta, continuar dividindo um número pela metade até chegar a 1. Para esses casos, o loop while se encaixa naturalmente: ele simplesmente repete enquanto uma condição permanecer verdadeira.
Um loop while verifica sua condição antes de cada passagem, inclusive a primeira. Se a condição já for falsa no início, o corpo nunca executa.
A condição count > 0 é verificada primeiro; se for verdadeira, o corpo executa; depois voltamos ao início e verificamos de novo. A linha count-- é o que acaba tornando a condição falsa; remova-a e o loop executa para sempre.
A anatomia de um loop while
Compare-o com o loop for de três partes que você já conhece. Um loop while separa esses três trabalhos: você faz a inicialização antes do loop, a condição vai entre parênteses e a atualização fica dentro do corpo.
int i = 0; // inicialização - antes do loop
while (i < 5) { // condição - verificada a cada passagem
System.out.println(i);
i++; // atualização - você mesmo precisa lembrar disso
}
Essa última parte é a pegadinha. Em um loop for a atualização fica logo ao lado da condição, então é difícil esquecê-la. Em um loop while ela é só mais uma instrução no corpo: o erro mais comum é deixá-la de fora e travar o programa.
do-while: executar o corpo pelo menos uma vez
Às vezes você precisa que o corpo execute uma vez antes de poder sequer decidir se vai repetir. O loop do-while verifica sua condição no final, então o corpo sempre executa pelo menos uma vez:
Você tem que pedir e ler pelo menos uma vez antes de saber se a entrada é válida, que é exatamente o que o do-while oferece. Note o ponto e vírgula depois de while (...): ele é obrigatório, e esquecê-lo é um erro de compilação frequente.
A diferença em relação a um while comum aparece claramente quando a condição começa falsa:
Só do-while body é impresso. O loop while pula seu corpo por completo porque x < 5 era falso antes da primeira verificação.
Iterar até um valor sentinela
Um uso clássico de while é ler até um valor especial de "parada": um sentinela. Aqui não há contador; você simplesmente continua até os dados mandarem você parar:
O padrão é ler uma vez antes do loop e depois ler de novo no final de cada passagem. Assim a condição sempre testa uma entrada nova. Se você esquecer a segunda leitura dentro do corpo, value nunca muda e você tem um loop infinito.
break e continue em loops while
break e continue funcionam aqui da mesma forma que em um loop for. break sai do loop imediatamente; continue pula direto para a verificação da condição, ignorando o restante da passagem atual:
Isso imprime 1 3 5 7 9. O while (true) deliberadamente nunca para por conta própria: o break é a única saída. Tenha cuidado com o continue em um loop while: como a atualização faz parte do corpo, voltar ao início com continue antes de ter avançado o contador é uma forma silenciosa de travar o loop. No exemplo acima, n++ executa primeiro, então é seguro.
Cuidado com loops infinitos
A condição precisa acabar se tornando falsa, e isso depende inteiramente de algo dentro do corpo mudar. Os dois culpados habituais são esquecer a atualização e atualizar do jeito errado:
int i = 0;
while (i < 5) {
System.out.println(i); // i nunca muda -> executa para sempre
}
int i = 0;
while (i != 10) {
i += 3; // 0, 3, 6, 9, 12... passa direto pelo 10 -> executa para sempre
}
O primeiro trava porque i nunca é atualizado. O segundo trava porque o contador passa por cima do valor exato que a condição procura; prefira < ou <= em vez de != quando o passo pode não cair exatamente no valor. Um while (true) é aceitável se tiver um break garantido; um acidental é apenas um bug.
Próximo: o loop for-each
Um loop while é a ferramenta certa quando você itera até uma condição mudar e não há uma contagem clara. Mas quando você só quer visitar cada elemento de um array ou de uma lista (sem índice, sem condição para gerenciar) há algo ainda mais limpo: o loop for-each aprimorado. Essa é a próxima página.
Perguntas frequentes
Qual é a diferença entre while e do-while em Java?
Um loop while verifica sua condição antes da primeira passagem, então o corpo pode executar zero vezes. Um loop do-while executa o corpo uma vez primeiro e depois verifica a condição no final, então ele sempre executa pelo menos uma vez. Use do-while quando o trabalho precisa acontecer antes de você poder decidir se vai repetir (como pedir uma entrada e depois validá-la).
Quando devo usar um loop while em vez de um for em Java?
Use um loop while quando você não tem um contador claro e só quer repetir até que alguma condição mude: ler entrada até o usuário digitar quit, verificar repetidamente até um valor ficar pronto ou processar uma fila até esvaziá-la. Recorra a um loop for quando souber o número de iterações ou tiver um índice óbvio para contar.
Como parar um loop while infinito em Java?
Garanta que algo dentro do corpo acabe tornando a condição falsa (decrementar um contador, avançar um ponteiro, definir uma flag). Para um loop while (true) intencional, coloque um break dentro, protegido por um if. Se um loop trava, a causa habitual é esquecer de atualizar a variável da qual a condição depende.