将Iterator向前移动到for语句和while语句之间的区别

时间:2022-10-18 18:02:12

When I use an Iterator of Object I use a while loop (as written in every book learning Java, as Thinking in Java of Bruce Eckel):

当我使用对象的Iterator时,我使用while循环(如每本书中学习Java,如Bruce Eckel的Thinking in Java):

Iterator it=...

while(it.hasNext()){
    //...
}

but sometime i saw than instead somebody use the for loop:

但有时我看到的是有人使用for循环:

Iterator it=...
for (Iterator it=...; it.hasNext();){
    //...
}

I don't' understand this choice:

我不明白这个选择:

  • I use the for loop when I have a collection with ordinal sequence (as array) or with a special rule for the step (declared generally as a simple increment counter++).
  • 当我有一个带有序数序列的集合(作为数组)或者带有一个特殊的步骤规则(通常声明为一个简单的增量计数器++)时,我使用for循环。

  • I use the while loop when the loop finishes with I have'nt this constraints but only a logic condition for exit.
  • 我在循环结束时使用while循环,我没有这个约束,但只有退出的逻辑条件。

It's a question of style-coding without other cause or it exists some other logic (performance, for example) that I don't' know?

这是一个没有其他原因的样式编码问题,或者存在一些我不知道的其他逻辑(例如性能)?

Thanks for every feedback

感谢您的每一个反馈

5 个解决方案

#1


The correct syntax for the for loop is:

for循环的正确语法是:

for (Iterator it = ...; it.hasNext(); ){
    //...
}

(The preceding declaration in your code is superfluous, as well as the extra semicolon in the for loop heading.)

(代码中的前面声明是多余的,以及for循环标题中的额外分号。)

Whether you use this syntax or the while loop is a matter of taste, both translate to exactly the same. The generic syntax of the for loop is:

无论你使用这种语法还是while循环是一个品味问题,两者都转化为完全相同。 for循环的通用语法是:

for (<init stmt>; <loop cond>; <iterate stmt>) { <body>; }

which is equivalent to:

这相当于:

<init stmt>;
while (<loop cond>) { <body>; <iterate stmt>; }

Edit: Actually, the above two forms are not entirely equivalent, if (as in the question) the variable is declared with the init statement. In this case, there will be a difference in the scope of the iterator variable. With the for loop, the scope is limited to the loop itself, in the case of the while loop, however, the scope extends to the end of the enclosing block (no big surprise, since the declaration is outside the loop).

编辑:实际上,如果(在问题中)变量是用init语句声明的,那么上面两种形式并不完全等价。在这种情况下,迭代器变量的范围会有所不同。对于for循环,范围仅限于循环本身,在while循环的情况下,范围扩展到封闭块的末尾(没有什么大惊喜,因为声明在循环之外)。

Also, as others have pointed out, in newer versions of Java, there is a shorthand notation for the for loop:

此外,正如其他人所指出的,在较新版本的Java中,for循环有一个简写符号:

for (Iterator<Foo> it = myIterable.iterator(); it.hasNext(); ) {
    Foo foo = it.next();
    //...
}

can be written as:

可以写成:

for (Foo foo : myIterable) {
    //...
}

With this form, you of course lose the direct reference to the iterator, which is necessary, for example, if you want to delete items from the collection while iterating.

使用此表单时,您当然会失去对迭代器的直接引用,这是必要的,例如,如果要在迭代时从集合中删除项目。

#2


It's just a style thing and like you I prefer the for loop when using something with an index. If you're using Java 5 you should of course use a foreach loop over the collection anyway:

它只是一种风格的东西,就像你在使用带索引的东西时我更喜欢for循环。如果你正在使用Java 5,你当然应该在集合上使用foreach循环:

Collection<String> someCollection = someCollectionOfString();
for (String element : someCollection) {
....
}

#3


The purpose of declaring the Iterator within the for loop is to minimize the scope of your variables, which is a good practice.

在for循环中声明迭代器的目的是最小化变量的范围,这是一种很好的做法。

When you declare the Iterator outside of the loop, then the reference is still valid / alive after the loop completes. 99.99% of the time, you don't need to continue to use the Iterator once the loop completes, so such a style can lead to bugs like this:

当您在循环外部声明Iterator时,循环完成后引用仍然有效/有效。 99.99%的时间,一旦循环完成,你不需要继续使用迭代器,所以这样的样式可能会导致这样的错误:

//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
}

#4


There isn't much difference between those two methods, other than the first one remembers the value of it after the loop. The second approach probably throws an error, because you redeclare the variable inside the loop.

这两种方法之间没有太大区别,除了第一种方法在循环之后记住它的值。第二种方法可能会抛出错误,因为您在循环内重新声明了变量。

There's actually a third method to this, aswell. Instead of writing e.g.

实际上还有第三种方法,以及。而不是写例如

for (Iterator<SomeObject> it = foo.iterator(); it.hasNext();) {
  SomeObject so = foo.next();
}

you can most often write

你最常写的

for (SomeObject so: foo) {...}

These two equal to the same thing...

这两个相同的东西......

#5


People may use the explicit ('old style') for loop simply because it feels cleaner to them, perhaps they haven't adjusted to the new syntax yet (which I personally think is a lot cleaner).

人们可以使用显式('旧样式')循环,因为它对他们来说感觉更干净,也许他们还没有适应新的语法(我个人认为它更清洁)。

One actual specific advantage of the longer for loop construct is that you have a reference to the iterator and so can call methods on it other then next(). In particular, hasNext() can often be useful to call - imagine if you want to print out a list of strings comma-separated:

循环结构的更长时间的一个实际特定优点是你有一个对迭代器的引用,因此可以在next()之外调用其他方法。特别是,hasNext()通常可用于调用 - 想象一下,如果要打印出以逗号分隔的字符串列表:

StringBuilder sb = new StringBuilder();
for (Iterator it=...; it.hasNext();){
   sb.append(it.next());
   if (it.hasNext())
      sb.append(", ");
}

It is only to distinguish the "this is the last one" case like this if you use the more verbose for loop.

如果你使用更详细的for循环,它只是区分“这是最后一个”这样的情况。

#1


The correct syntax for the for loop is:

for循环的正确语法是:

for (Iterator it = ...; it.hasNext(); ){
    //...
}

(The preceding declaration in your code is superfluous, as well as the extra semicolon in the for loop heading.)

(代码中的前面声明是多余的,以及for循环标题中的额外分号。)

Whether you use this syntax or the while loop is a matter of taste, both translate to exactly the same. The generic syntax of the for loop is:

无论你使用这种语法还是while循环是一个品味问题,两者都转化为完全相同。 for循环的通用语法是:

for (<init stmt>; <loop cond>; <iterate stmt>) { <body>; }

which is equivalent to:

这相当于:

<init stmt>;
while (<loop cond>) { <body>; <iterate stmt>; }

Edit: Actually, the above two forms are not entirely equivalent, if (as in the question) the variable is declared with the init statement. In this case, there will be a difference in the scope of the iterator variable. With the for loop, the scope is limited to the loop itself, in the case of the while loop, however, the scope extends to the end of the enclosing block (no big surprise, since the declaration is outside the loop).

编辑:实际上,如果(在问题中)变量是用init语句声明的,那么上面两种形式并不完全等价。在这种情况下,迭代器变量的范围会有所不同。对于for循环,范围仅限于循环本身,在while循环的情况下,范围扩展到封闭块的末尾(没有什么大惊喜,因为声明在循环之外)。

Also, as others have pointed out, in newer versions of Java, there is a shorthand notation for the for loop:

此外,正如其他人所指出的,在较新版本的Java中,for循环有一个简写符号:

for (Iterator<Foo> it = myIterable.iterator(); it.hasNext(); ) {
    Foo foo = it.next();
    //...
}

can be written as:

可以写成:

for (Foo foo : myIterable) {
    //...
}

With this form, you of course lose the direct reference to the iterator, which is necessary, for example, if you want to delete items from the collection while iterating.

使用此表单时,您当然会失去对迭代器的直接引用,这是必要的,例如,如果要在迭代时从集合中删除项目。

#2


It's just a style thing and like you I prefer the for loop when using something with an index. If you're using Java 5 you should of course use a foreach loop over the collection anyway:

它只是一种风格的东西,就像你在使用带索引的东西时我更喜欢for循环。如果你正在使用Java 5,你当然应该在集合上使用foreach循环:

Collection<String> someCollection = someCollectionOfString();
for (String element : someCollection) {
....
}

#3


The purpose of declaring the Iterator within the for loop is to minimize the scope of your variables, which is a good practice.

在for循环中声明迭代器的目的是最小化变量的范围,这是一种很好的做法。

When you declare the Iterator outside of the loop, then the reference is still valid / alive after the loop completes. 99.99% of the time, you don't need to continue to use the Iterator once the loop completes, so such a style can lead to bugs like this:

当您在循环外部声明Iterator时,循环完成后引用仍然有效/有效。 99.99%的时间,一旦循环完成,你不需要继续使用迭代器,所以这样的样式可能会导致这样的错误:

//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
}

#4


There isn't much difference between those two methods, other than the first one remembers the value of it after the loop. The second approach probably throws an error, because you redeclare the variable inside the loop.

这两种方法之间没有太大区别,除了第一种方法在循环之后记住它的值。第二种方法可能会抛出错误,因为您在循环内重新声明了变量。

There's actually a third method to this, aswell. Instead of writing e.g.

实际上还有第三种方法,以及。而不是写例如

for (Iterator<SomeObject> it = foo.iterator(); it.hasNext();) {
  SomeObject so = foo.next();
}

you can most often write

你最常写的

for (SomeObject so: foo) {...}

These two equal to the same thing...

这两个相同的东西......

#5


People may use the explicit ('old style') for loop simply because it feels cleaner to them, perhaps they haven't adjusted to the new syntax yet (which I personally think is a lot cleaner).

人们可以使用显式('旧样式')循环,因为它对他们来说感觉更干净,也许他们还没有适应新的语法(我个人认为它更清洁)。

One actual specific advantage of the longer for loop construct is that you have a reference to the iterator and so can call methods on it other then next(). In particular, hasNext() can often be useful to call - imagine if you want to print out a list of strings comma-separated:

循环结构的更长时间的一个实际特定优点是你有一个对迭代器的引用,因此可以在next()之外调用其他方法。特别是,hasNext()通常可用于调用 - 想象一下,如果要打印出以逗号分隔的字符串列表:

StringBuilder sb = new StringBuilder();
for (Iterator it=...; it.hasNext();){
   sb.append(it.next());
   if (it.hasNext())
      sb.append(", ");
}

It is only to distinguish the "this is the last one" case like this if you use the more verbose for loop.

如果你使用更详细的for循环,它只是区分“这是最后一个”这样的情况。