Java:如果使用 for-each 循环遍历集合,则替代 iterator.hasNext()
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1782933/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java: Alternative to iterator.hasNext() if using for-each to loop over a collection
提问by Dan Burzo
I'm trying to replace an iterator-based loop over a Java list with a for-each
statement, but the code uses at some point iterator.hasNext()
to check if it reached the last element in the list.
我试图用for-each
语句替换 Java 列表上基于迭代器的循环,但代码在某些时候使用iterator.hasNext()
它来检查它是否到达列表中的最后一个元素。
Is there something similar for the for-each
alternative?
有没有类似的for-each
替代方案?
for (Object current : objectList) {
if (last-element)
do-something-special
}
采纳答案by Mirek Pluta
for-each is just syntactic sugar for iterator version and if you check compiled bytecode, then you'll notice that compilator actually change it into iterator version.
for-each 只是迭代器版本的语法糖,如果您检查编译后的字节码,那么您会注意到编译器实际上将其更改为迭代器版本。
With a for-each form you can't check whether you'll have more elements or not. Just stay with explicit iterator use if you need that feature.
使用 for-each 表单,您无法检查是否有更多元素。如果您需要该功能,请继续使用显式迭代器。
回答by PeterMmm
If you want to stay with for-each maybe something like this:
如果你想留下 for-each 可能是这样的:
if (objectList.indexOf(current)==objectList.size()-1) break;
回答by Jorn
Unfortunately, the for each idiom does not allow you to check if an element is first or last in the list. This is a known limitation of the for each loop. I suggest you just keep using the iterator.
不幸的是, for each 成语不允许您检查元素是列表中的第一个还是最后一个。这是 for each 循环的已知限制。我建议你继续使用迭代器。
If you can also check for the first element instead of the last one, for example if you're doing String concatenation, you could change to something like:
如果您还可以检查第一个元素而不是最后一个元素,例如,如果您正在进行字符串连接,则可以更改为:
boolean first = true;
for (Element e : list) {
if (!first) {
//do optional operation
}
//do other stuff
first = false;
}
but I would prefer using the iterator.
但我更喜欢使用迭代器。
回答by Carl Smotricz
int nElts = objectList.size();
int n = 0;
for (...) {
if (++n == nElts) ...
is the best I can think of.
是我能想到的最好的。
回答by coobird
The foreach
loop (or enhanced for
loop) does not have facilities to keep track of which element is being iterated on at the moment. There is no way to find out which index of a Collection
is being worked on, or whether there are more elements to be processed in an Iterable
.
该foreach
环(或增强的for
循环)没有设施,以跟踪哪些元素是目前正在迭代上。无法找出Collection
正在处理的 a 的哪个索引,或者在Iterable
.
That said, one workaround that would work is to keep a reference to the object which is being iterated on at the moment in the foreach
loop.
也就是说,一种可行的解决方法是保留对foreach
循环中正在迭代的对象的引用。
By keeping a reference of what it being worked on at the current iteration, one would be able to keep the reference once the foreach
loop ends, and what is left in the variable will be the last element.
通过保留当前迭代中正在处理的内容的引用,一旦foreach
循环结束,就可以保留引用,变量中剩下的将是最后一个元素。
This workaround will only work if-and-only-if the last element is the only element which is needed.
此解决方法仅当最后一个元素是唯一需要的元素时才有效。
For example:
例如:
String lastString = null;
for (String s : new String[] {"a", "b", "c"}) {
// Do something.
// Keep the reference to the current object being iterated on.
lastString = s;
}
System.out.println(lastString);
Output:
输出:
c
回答by Andreas Dolk
In addition to Luno's answer:
除了 Luno 的回答:
Iterator<MyClass> it = myCollection.iterator();
while(it.hasNext()) {
MyClass myClass = it.next():
// do something with myClass
}
translates to:
翻译成:
for (MyClass myClass:myCollection) {
// do something with myClass
}
回答by Andrzej Doyle
As others have said - this isn't possible.
正如其他人所说 - 这是不可能的。
Just remember that the foreach construct isn't the be-all and end-all. It was introduced to make the very common task of performing the same operations on each element of a collectionsimpler to denote.
请记住,foreach 结构并不是万能的。引入它是为了使对集合的每个元素执行相同操作的非常常见的任务更易于表示。
In your case, you don't want to do exactly the same thing to each element - and thus a foreach loop is not the right tool for the job. Trying to "hack" it into doing this is silly, just use an explicit iterator in a classic for loop.
在您的情况下,您不想对每个元素做完全相同的事情 - 因此 foreach 循环不是该工作的正确工具。试图“破解”它这样做很愚蠢,只需在经典的 for 循环中使用显式迭代器即可。
回答by Monachus
There are two possible cases where you would like to do this.
有两种可能的情况,您希望这样做。
- You need to do something after the last element has been reached: in this case you just need to put your code outside of the loop.
for(Object item:theLinkedList){
}
System.out.println("something special")
you need to modify the last element in some way or use information related to the last element. In this case you should use the **LinkedList** to access the last element- 您需要在到达最后一个元素后做一些事情:在这种情况下,您只需要将代码放在循环之外。
for(Object item:theLinkedList){
}
System.out.println("something special")
您需要以某种方式修改最后一个元素或使用与最后一个元素相关的信息。在这种情况下,您应该使用 **LinkedList** 访问最后一个元素
for(Object item:theLinkedList){
}
Object last=theLinkedList.getLast();
System.out.println("last");
回答by bayer
yes you can, here's how i would do it if you don't want to use the explicit iterator syntax:
是的,你可以,如果你不想使用显式迭代器语法,我会这样做:
for (Object current : objectList) {
if (objectList.getLast().equals(current))
do-something-special
}
回答by Erik Wolf
In Addition to bayer you have to do it a bit different because there is no method getLast()
. But instead of it you can use this objectList.size() - 1
.
除了拜耳,你必须做一点不同的,因为没有方法getLast()
。但是,您可以使用 this 代替它objectList.size() - 1
。
for (Object current : objectList) {
if (objectList.get(objectList.size() - 1).equals(current))
do-something-special
}