Diferença entre mover um Iterator para a frente com uma instrução e uma declaração enquanto
-
21-08-2019 - |
Pergunta
Quando eu usar um Iterator do objeto i usar um while (como está escrito em cada livro aprendendo Java, como Thinking in Java de Bruce Eckel):
Iterator it=...
while(it.hasNext()){
//...
}
mas viu algum i que em vez uso a alguém o loop :
Iterator it=...
for (Iterator it=...; it.hasNext();){
//...
}
Eu não' entender esta escolha:
- Eu uso o loop quando eu tenho uma coleção com sequência ordinal (como matriz) ou com uma regra especial para o passo (declarada geralmente como um simples
counter++
incremento). - Eu uso o while quando os acabamentos loop com I have'nt este restrições, mas apenas uma condição lógica para a saída.
É uma questão de estilo de codificação sem outra causa ou existe alguma outra lógica (performance, por exemplo) que eu não' sabe?
Obrigado por todos os comentários
Solução
A sintaxe correta para o loop for é:
for (Iterator it = ...; it.hasNext(); ){
//...
}
(A declaração anterior em seu código é supérfluo, bem como o ponto e vírgula extra no para título loop.)
Se você usa esta sintaxe ou o loop while
é uma questão de gosto, tanto traduzir para exatamente o mesmo. A sintaxe genérica do loop for é:
for (<init stmt>; <loop cond>; <iterate stmt>) { <body>; }
o que equivale a:
<init stmt>;
while (<loop cond>) { <body>; <iterate stmt>; }
Editar: Na verdade, o acima duas formas não são inteiramente equivalentes, se (como na questão) a variável é declarada com a instrução de inicialização. Neste caso, haverá uma diferença no âmbito da variável iteração. Com o ciclo for, o âmbito é limitado ao próprio circuito, no caso do while, no entanto, o âmbito de aplicação se estende até ao fim do bloco de inclusão (sem grande surpresa, uma vez que a declaração está fora do ciclo).
Além disso, como os outros têm para fora pontas, nas versões mais recentes do Java, há uma notação abreviada para o loop for:
for (Iterator<Foo> it = myIterable.iterator(); it.hasNext(); ) {
Foo foo = it.next();
//...
}
pode ser escrita como:
for (Foo foo : myIterable) {
//...
}
Com este formulário, você naturalmente perder a referência direta ao iterador, que é necessário, por exemplo, se você deseja excluir os itens da coleção durante a iteração.
Outras dicas
É apenas uma coisa estilo e como você eu prefiro o loop for ao usar algo com um índice. Se você estiver usando Java 5, você deve, naturalmente, usar um loop foreach sobre a coleta de qualquer maneira:
Collection<String> someCollection = someCollectionOfString();
for (String element : someCollection) {
....
}
A fim de declarar a Iterator
dentro do loop for é minimizar o escopo de suas variáveis ??, que é uma boa prática.
Quando você declara o exterior Iterator
do loop, em seguida, a referência ainda é válido / vivo depois da conclusão do laço. 99,99% do tempo, você não precisa continuar a usar o Iterator
uma vez que os concluída laço, de modo tal estilo pode levar a erros como este:
//iterate over first collection
Iterator it1 = collection1.iterator();
while(it1.hasNext()) {
//blah blah
}
//iterate over second collection
Iterator it2 = collection2.iterator();
while(it1.hasNext()) {
//oops copy and paste error! it1 has no more elements at this point
}
Não há muita diferença entre esses dois métodos, que não seja o primeiro lembra o valor da it
após o loop. A segunda abordagem, provavelmente, gera um erro, porque você redeclare a variável dentro do ciclo.
Na verdade, há um terceiro método para isso, cabeceira. Em vez de escrever por exemplo.
for (Iterator<SomeObject> it = foo.iterator(); it.hasNext();) {
SomeObject so = foo.next();
}
pode mais frequentemente escrever
for (SomeObject so: foo) {...}
Estes dois iguais à mesma coisa ...
As pessoas podem usar a explícita ( 'estilo antigo') loop for simplesmente porque ele se sente mais limpo para eles, talvez eles não tenham ajustado para a nova sintaxe ainda (o que eu acho, pessoalmente, é muito mais limpo).
Uma vantagem específica real da mais longa para construção de loop é que você tem uma referência para o iterador e assim pode chamar métodos nele outra next()
então. Em particular, hasNext()
muitas vezes pode ser útil para call - imagine se você pretende imprimir uma lista de cadeias separadas por vírgula:
StringBuilder sb = new StringBuilder();
for (Iterator it=...; it.hasNext();){
sb.append(it.next());
if (it.hasNext())
sb.append(", ");
}
É apenas para distinguir o "este é o último" caso como este se você usar o mais detalhado para loop.