使用 for 语句和 while 语句向前移动迭代器的区别
Posted
技术标签:
【中文标题】使用 for 语句和 while 语句向前移动迭代器的区别【英文标题】:Difference between moving an Iterator forward with a for statement and a while statement 【发布时间】:2010-10-05 15:49:34 【问题描述】:当我使用对象的迭代器时,我会使用 while 循环(正如每本学习 Java 的书中所写的那样,如 Bruce Eckel 的 Thinking in Java):
Iterator it=...
while(it.hasNext())
//...
但有时我看到有人使用 for 循环:
Iterator it=...
for (Iterator it=...; it.hasNext();)
//...
我不明白这个选择:
我使用 for 循环,当我有一个带有序数序列(作为数组)的集合或具有特定步骤规则(通常声明为简单增量counter++
)的集合时。
当循环结束时,我使用 while 循环,但我没有这个约束,只有退出的逻辑条件。
这是一个没有其他原因的样式编码问题,或者它存在一些我不知道的其他逻辑(例如性能)?
感谢您的每一个反馈
【问题讨论】:
在***.com/questions/2598219/…中有一个将Iterator
转换为兼容for-each循环Iterable
的例子
【参考方案1】:
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>;
编辑:其实以上两种形式并不完全等价,if(如题)变量是用init语句声明的。在这种情况下,迭代器变量的范围会有所不同。对于 for 循环,范围仅限于循环本身,但是在 while 循环的情况下,范围会扩展到封闭块的末尾(不足为奇,因为声明在循环之外)。
另外,正如其他人指出的那样,在较新版本的 Java 中,for 循环有一个简写符号:
for (Iterator<Foo> it = myIterable.iterator(); it.hasNext(); )
Foo foo = it.next();
//...
可以写成:
for (Foo foo : myIterable)
//...
使用这种形式,您当然会失去对迭代器的直接引用,这是必需的,例如,如果您想在迭代时从集合中删除项目。
【讨论】:
如果您添加对使用“for”循环获得的有限范围的引用,这将成为完美的答案......【参考方案2】:这只是一种风格,和你一样,在使用带有索引的东西时,我更喜欢 for 循环。如果您使用的是 Java 5,那么您当然应该在集合上使用 foreach 循环:
Collection<String> someCollection = someCollectionOfString();
for (String element : someCollection)
....
【讨论】:
使用这种形式的迭代器唯一会失去的是你不能调用 Iterator.remove() 方法——因为你没有对 Iterator 对象的引用。 没错.. 但你很快就会发现这一点!【参考方案3】:在 for 循环中声明 Iterator
的目的是最小化变量的范围,这是一个很好的做法。
当您在循环外声明 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
【讨论】:
【参考方案4】:这两种方法没有太大区别,除了第一种在循环后记住it
的值。第二种方法可能会引发错误,因为您在循环内重新声明了变量。
实际上还有第三种方法。而不是写例如
for (Iterator<SomeObject> it = foo.iterator(); it.hasNext();)
SomeObject so = foo.next();
你最常写
for (SomeObject so: foo) ...
这两个等于同一个东西……
【讨论】:
【参考方案5】:人们可能会使用显式('旧样式')for循环,只是因为他们觉得它更干净,也许他们还没有适应新语法(我个人认为它更干净)。
较长的 for 循环构造的一个实际特定优势是您可以引用迭代器,因此可以在其上调用除 next()
之外的方法。特别是,hasNext()
调用起来通常很有用 - 想象一下,如果您想打印一个以逗号分隔的字符串列表:
StringBuilder sb = new StringBuilder();
for (Iterator it=...; it.hasNext();)
sb.append(it.next());
if (it.hasNext())
sb.append(", ");
如果你使用更冗长的for循环,这只是为了区分“这是最后一个”的情况。
【讨论】:
以上是关于使用 for 语句和 while 语句向前移动迭代器的区别的主要内容,如果未能解决你的问题,请参考以下文章