15

当我使用对象的迭代器时,我使用了一个while 循环(如每本学习 Java 的书中所写,如Bruce Eckel 的Thinking in Java ):

Iterator it=...

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

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

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

我不明白这个选择:

  • 当我有一个带有序数序列(作为数组)的集合或具有用于步骤的特殊规则(通常声明为简单增量)的集合时,我使用for 循环counter++
  • 当循环结束时我使用while循环,我没有这个约束,但只有一个退出的逻辑条件。

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

感谢您的每一个反馈

4

5 回答 5

32

for 循环的正确语法是:

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

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

无论您是使用这种语法还是while循环,都取决于您的喜好,两者都转换为完全相同的内容。for 循环的通用语法是:

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

这相当于:

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

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

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

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

可以写成:

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

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

于 2009-02-05T11:54:20.230 回答
9

这只是一种风格,和你一样,在使用带有索引的东西时,我更喜欢 for 循环。如果您使用的是 Java 5,那么您当然应该在集合上使用 foreach 循环:

Collection<String> someCollection = someCollectionOfString();
for (String element : someCollection) {
....
}
于 2009-02-05T11:54:19.790 回答
9

Iterator在 for 循环内声明的目的是最小化变量的范围,这是一个很好的做法。

当您声明Iterator循环外部时,循环完成后引用仍然有效/有效。99.99% 的情况下,您不需要Iterator在循环完成后继续使用,因此这种样式可能会导致如下错误:

//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
}
于 2009-02-05T14:40:34.700 回答
4

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

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

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

你最常写

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

这两个等于同一个东西...

于 2009-02-05T11:57:19.550 回答
2

人们可能会使用显式('旧样式')for循环,只是因为他们觉得它更干净,也许他们还没有适应新语法(我个人认为它更干净)。

较长的 for 循环构造的一个实际特定优势是您可以引用迭代器,因此可以在其上调用其他方法 then next()。特别是,hasNext()调用通常很有用 - 想象一下,如果你想打印出一个以逗号分隔的字符串列表:

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

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

于 2009-02-05T11:56:57.447 回答