使用 for 语句和 while 语句向前移动迭代器的区别
-
21-08-2019 - |
题
当我使用对象的迭代器时,我使用 while 循环 (正如每本学习 Java 的书中所写的那样, 用Java思考 布鲁斯·埃克尔):
Iterator it=...
while(it.hasNext()){
//...
}
但有时我看到有人使用 for循环:
Iterator it=...
for (Iterator it=...; it.hasNext();){
//...
}
我不明白这个选择:
- 我用 for循环 当我有一个带有序数序列(作为数组)或带有特殊步骤规则(通常声明为简单增量)的集合时
counter++
). - 我用 while 循环 当循环结束时,我没有这个约束,而只有退出的逻辑条件。
这是一个没有其他原因的风格编码问题,或者存在一些我不知道的其他逻辑(例如性能)?
感谢您的每一个反馈
解决方案
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) {
//...
}
使用这种形式,您当然会失去对迭代器的直接引用,这是必要的,例如,如果您想在迭代时从集合中删除项目。
其他提示
这只是一种风格,像你一样,我在使用带有索引的东西时更喜欢 for 循环。如果您使用的是 Java 5,您当然应该对集合使用 foreach 循环:
Collection<String> someCollection = someCollectionOfString();
for (String element : someCollection) {
....
}
声明的目的 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
}
这两种方法没有太大区别,除了第一种方法记住了 it
循环之后。第二种方法可能会引发错误,因为您在循环内重新声明了变量。
实际上还有第三种方法。而不是写例如
for (Iterator<SomeObject> it = foo.iterator(); it.hasNext();) {
SomeObject so = foo.next();
}
你通常可以写
for (SomeObject so: foo) {...}
这两个等于同一个东西...
人们可能会使用显式(“旧式”)for 循环,只是因为他们觉得它更干净,也许他们还没有适应新语法(我个人认为新语法更干净)。
较长的 for 循环构造的一个实际具体优点是您拥有对迭代器的引用,因此可以调用它的其他方法 next()
. 。尤其, hasNext()
调用通常很有用 - 想象一下,如果您想打印出以逗号分隔的字符串列表:
StringBuilder sb = new StringBuilder();
for (Iterator it=...; it.hasNext();){
sb.append(it.next());
if (it.hasNext())
sb.append(", ");
}
如果您使用更详细的 for 循环,它只是为了区分“这是最后一个”情况。