Java 迭代器 vs for
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22267919/
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
Iterator vs for
提问by rocking
I was asked in an interview what is the advantage of using iterator using for loop or what is the advantage of using for loop over iterator?
我在一次采访中被问到使用 for 循环的迭代器有什么好处,或者使用 for 循环而不是迭代器有什么好处?
Can any body please answer this so that in future If I face similar question then I can answer that
任何机构都可以回答这个问题,以便将来如果我遇到类似的问题,那么我可以回答
采纳答案by JB Nizet
First of all, there are 2 kinds of for loops, which behave very differently. One uses indices:
首先,有两种 for 循环,它们的行为非常不同。一种使用索引:
for (int i = 0; i < list.size(); i++) {
Thing t = list.get(i);
...
}
This kind of loop isn't always possible. For example, Lists have indices, but Sets don't, because they're unordered collections.
这种循环并不总是可能的。例如,列表有索引,但集合没有,因为它们是无序集合。
The other one, the foreach loop uses an Iterator behind the scenes:
另一个,foreach 循环在幕后使用了一个迭代器:
for (Thing thing : list) {
...
}
This works with every kind of Iterable collection (or array)
这适用于各种 Iterable 集合(或数组)
And finally, you can use an Iterator, which also works with any Iterable:
最后,您可以使用迭代器,它也适用于任何迭代器:
for (Iterator<Thing> it = list.iterator(); it.hasNext(); ) {
Thing t = it.next();
...
}
So you in fact have 3 loops to compare.
所以你实际上有 3 个循环来比较。
You can compare them in different terms: performance, readability, error-proneness, capability.
您可以从不同方面比较它们:性能、可读性、易错性、功能。
An Iterator can do things that a foreach loop can't. For example, you can remove elements while you're iterating, if the iterator supports it:
Iterator 可以做 foreach 循环不能做的事情。例如,您可以在迭代时删除元素,如果迭代器支持它:
for (Iterator<Thing> it = list.iterator(); it.hasNext(); ) {
Thing t = it.next();
if (shouldBeDeleted(thing) {
it.remove();
}
}
Lists also offer iterators that can iterate in both directions. A foreach loop only iterates from the beginning to an end.
列表还提供了可以双向迭代的迭代器。foreach 循环仅从开始到结束进行迭代。
But an Iterator is more dangerous and less readable. When a foreach loop is all you need, it's the most readable solution. With an iterator, you could do the following, which would be a bug:
但是迭代器更危险,可读性更差。当您只需要 foreach 循环时,它就是最易读的解决方案。使用迭代器,您可以执行以下操作,这将是一个错误:
for (Iterator<Thing> it = list.iterator(); it.hasNext(); ) {
System.out.println(it.next().getFoo());
System.out.println(it.next().getBar());
}
A foreach loop doesn't allow for such a bug to happen.
foreach 循环不允许发生这样的错误。
Using indices to access elements is slightly more efficient with collections backed by an array. But if you change your mind and use a LinkedList instead of an ArrayList, suddenly the performance will be awful, because each time you access list.get(i)
, the linked list will have to loop though all its elements until the ith one. An Iterator (and thus the foreach loop) doesn't have this problem. It always uses the best possible way to iterate through elements of the given collection, because the collection itself has its own Iterator implementation.
对于由数组支持的集合,使用索引访问元素的效率稍高一些。但是,如果您改变主意并使用 LinkedList 而不是 ArrayList,那么性能会突然变得很糟糕,因为每次访问 时list.get(i)
,链表都必须循环遍历其所有元素,直到第 i 个元素。迭代器(以及 foreach 循环)没有这个问题。它总是使用最好的方式遍历给定集合的元素,因为集合本身有它自己的迭代器实现。
My general rule of thumb is: use the foreach loop, unless you really need capabilities of an Iterator. I would only use for loop with indices with arrays, when I need access to the index inside the loop.
我的一般经验法则是:使用 foreach 循环,除非您确实需要迭代器的功能。当我需要访问循环内的索引时,我只会使用带有数组索引的 for 循环。
回答by Salah
Iterator Advantage:
迭代器优势:
- Ability to remove elements from Collections.
- Ability to move forward and backward using
next()
andprevious()
. - Ability to check if there more elements or not by using
hasNext()
.
- 能够从集合中删除元素。
- 能够使用
next()
和向前和向后移动previous()
。 - 能够通过使用检查是否有更多元素
hasNext()
。
Loop was designed only to iterate over a Collection
, so if you want just to iterate over a Collection
, its better to use loop such as for-Each
, but if you want more that that you could use Iterator.
Loop 仅设计为迭代 a Collection
,因此如果您只想迭代 a Collection
,最好使用诸如 的循环for-Each
,但如果您想要更多,则可以使用 Iterator。
回答by user3392677
if you access to data by number (e.g. "i"), it is fast when you use array. because it goes to element directly
如果您按数字(例如“i”)访问数据,则使用数组时速度会很快。因为它直接转到元素
But, other data structure (e.g. tree, list), it needs more time, because it start from first element to target element. when you use list. It needs time O(n). so, it is to be slow.
但是,其他数据结构(例如树、列表),它需要更多时间,因为它从第一个元素开始到目标元素。当您使用列表时。它需要时间 O(n)。所以,它是缓慢的。
if you use iterator, compiler knows that where you are. so It needs O(1) (because, it start from current position)
如果你使用迭代器,编译器就会知道你在哪里。所以它需要 O(1)(因为它从当前位置开始)
finally, if you use only array or data structure that support direct access(e.g. arraylist at java). "a[i]" is good. but, when you use other data structure, iterator is more efficient
最后,如果您只使用支持直接访问的数组或数据结构(例如 java 中的数组列表)。“a[i]”很好。但是,当您使用其他数据结构时,迭代器效率更高
回答by xburgos
The main difference between Iterator and the classic for loop, apart from the obvious one of having or not having access to the index of the item you're iterating, is that using Iterator abstracts the client code from the underlying collection implementation, allow me to elaborate.
Iterator 和经典 for 循环之间的主要区别,除了可以访问或不能访问您正在迭代的项目的索引的明显区别之外,还在于使用 Iterator 将客户端代码从底层集合实现中抽象出来,允许我精心制作的。
When your code uses an iterator, either in this form
当您的代码使用迭代器时,无论是在这种形式
for(Item element : myCollection) { ... }
this form
这个表格
Iterator<Item> iterator = myCollection.iterator();
while(iterator.hasNext()) {
Item element = iterator.next();
...
}
or this form
或者这个表格
for(Iterator iterator = myCollection.iterator(); iterator.hasNext(); ) {
Item element = iterator.next();
...
}
What your code is saying is "I don't care about the type of collection and its implementation, I just care that I can iterate through its elements". Which is usually the better approach, since it makes your code more decoupled.
您的代码所说的是“我不关心集合的类型及其实现,我只关心我可以遍历它的元素”。这通常是更好的方法,因为它使您的代码更加解耦。
On the other hand, if you're using the classic for loop, as in
另一方面,如果您使用经典的 for 循环,如
for(int i = 0; i < myCollection.size(); i++) {
Item element = myCollection.get(i);
...
}
Your code is saying, I need to know the type of collection, because I need to iterate through its elements in a specific way, I'm also possibly going to check for nulls or compute some result based on the order of iteration. Which makes your code more fragile, because if at any point the type of collection you receive changes, it will impact the way your code works.
您的代码说,我需要知道集合的类型,因为我需要以特定方式遍历其元素,我还可能会检查空值或根据迭代顺序计算一些结果。这使您的代码更加脆弱,因为如果您收到的集合类型在任何时候发生变化,它将影响您的代码的工作方式。
Summing it up, the difference is not so much about speed, or memory usage, is more about decoupling your code so that is more flexible to cope with change.
总结起来,差异不在于速度或内存使用,而在于解耦您的代码,以便更灵活地应对变化。
回答by fgul
Unlike other answers, I want to point another things;
与其他答案不同,我想指出另一件事;
if you need to perform the iteration in more than one place in your code, you will likely end up duplicating the logic. This clearly isn't a very extensible approach. Instead, what's needed is a way to separate the logic for selecting the data from the code that actually processes it.
如果您需要在代码中的多个地方执行迭代,则最终可能会复制逻辑。这显然不是一个非常可扩展的方法。相反,需要的是一种将选择数据的逻辑与实际处理数据的代码分开的方法。
An iteratorsolves these problems by providing a generic interface for looping over a set of data so that the underlying data structure or storage mechanism — such as an array- is hidden.
一个迭代诸如基于阵列被隐藏-通过用于循环在一组数据,使得底层数据结构或存储机制提供的通用接口来解决这些问题。
- Iterator is a concept not an implementation.
- An iterator provides a number of operations for traversing and accessing data.
- An iterator may wrap any datastructure like array.
- One of the more interesting and useful advantages of using iterators is the capability to wrap or decorate another iterator to filter the return values
- An iterator may be thread safe while a for loop alone cannot be as it is accessing elements directly. The only popular thread-safety iterator is
CopyOnWriteArrayList
but it is well known and used often so worth mentioning.
- 迭代器是一个概念而不是一个实现。
- 迭代器提供了许多遍历和访问数据的操作。
- 迭代器可以包装任何数据结构,如数组。
- 使用迭代器的一个更有趣和有用的优点是能够包装或装饰另一个迭代器来过滤返回值
- 迭代器可能是线程安全的,而单独的 for 循环不能是线程安全的,因为它直接访问元素。唯一流行的线程安全迭代器是
CopyOnWriteArrayList
但它是众所周知的并且经常使用,所以值得一提。
This is from the book that it is https://www.amazon.com/Beginning-Algorithms-Simon-Harris/dp/0764596748
这是从书中说它是https://www.amazon.com/Beginning-Algorithms-Simon-Harris/dp/0764596748