Diferença entre mover um Iterator para a frente com uma instrução e uma declaração enquanto

StackOverflow https://stackoverflow.com/questions/515562

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

Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top