109

I was asked in an interview what is the advantage of using iterator over for loop or what is the advantage of using for loop over iterator?

Can any body please answer this?

Anatoly
  • 20,799
  • 3
  • 28
  • 42
rocking
  • 4,729
  • 9
  • 30
  • 45
  • Just curious: what did you answer? – donfuxx Mar 08 '14 at 10:12
  • 2
    A for-each loop uses an iterator under the covers. The difference is just readability (and therefore maintainability). – Dawood ibn Kareem Mar 08 '14 at 10:13
  • @donfuxx at first they asked which is better iterator or for loop.I said iterator and after that they asked why? – rocking Mar 08 '14 at 10:14
  • see this question here: http://stackoverflow.com/questions/2113216/which-is-more-efficient-a-for-each-loop-or-an-iterator – donfuxx Mar 08 '14 at 10:15
  • An Iterator allows removing items while iterating. But a foreach loop is more readable, and has less chance for bugs. – JB Nizet Mar 08 '14 at 10:15
  • @DavidWallace Thanks for answering.Can you please provide detail explanations because in interview they will ask me in detail – rocking Mar 08 '14 at 10:16
  • 1
    Well; why did you say `Iterator`? – Boris the Spider Mar 08 '14 at 10:16
  • @BoristheSpider I dont know the reason just said iterator.I can not say that I dont know – rocking Mar 08 '14 at 10:17
  • IMHO, iterator is more readable, yet you use the sense of 'index'. So my answer would be for loops, at least for arrays. – Engin Kayraklioglu Mar 08 '14 at 10:17
  • @JBNizet If I say I dont know then interviewer may think that I have not even tried,It all depends on the mentallity.Isnt it? – rocking Mar 08 '14 at 10:21
  • 3
    Nothing forces you to answer immediately. You can reason about the different kinds of collections, what each code does behind the scene, and show your ability to reason, even if you can't formulate a definitive answer. That's what is important: being able to think. I would start my answer with: "well, I don't know. I guess it depends on what you want to do, and what the kind of collection is. There must be a good reason to use both, but it must depend on the situation. Let's imagine what happens with an ArrayList. Then with a LinkedList. etc. etc." – JB Nizet Mar 08 '14 at 10:25
  • 3
    I agree entirely with @JBNizet. Saying I don't know it much better than picking a random option - that gives me the impression that you would do that while programming; pick the first thing that comes to mind without thinking. You could try and explain your knowledge in the area than say that you don't know enough to give an informed answer. – Boris the Spider Mar 08 '14 at 10:26
  • @BoristheSpider I got 2 answers till now,Which one do you think is more appropriate so That I will accpet as the best one – rocking Mar 08 '14 at 10:27
  • @JBNizet Do I have to wait for other answers and Out of the 2 I will accept one as the best answer – rocking Mar 08 '14 at 10:28
  • 2
    Both current answers are incomplete. First of all, there are 2 kinds of for loops, which behave very differently. One uses indices (which isn't always possible), and the other one uses an Iterator behind the scenes. So you in fact have 3 loops to compare. Then you can compare them in different terms: performance, readability, error-proneness, capability. An Iterator can do things that a foreach loop can't. But an Iterator is more dangerous and less readable. And using indices to access elements is only doable with Lists, but is not efficient if it's a linked list. So there's no "best" way. – JB Nizet Mar 08 '14 at 10:34
  • @JBNizet if you turn that last comment into an answer (maybe minus the first sentence) I will upvote it. – Dawood ibn Kareem Mar 08 '14 at 10:35
  • @JBNizet I will also upvote and in the future you may also get upvotes – rocking Mar 08 '14 at 10:39
  • A scenario where a for loop would benefit in keeping the code simple and more efficient: http://stackoverflow.com/q/31222023/2220216. Here, we need to iterate over consecutive pairs of elements, and using a for loop is better suited. – dshgna Jul 04 '15 at 15:18

6 Answers6

174

First of all, there are 2 kinds of for loops, which behave very differently. One uses indices:

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:

for (Thing thing : list) {
    ...
}

This works with every kind of Iterable collection (or array)

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.

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:

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.

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:

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.

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.

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.

phlaxyr
  • 923
  • 1
  • 8
  • 22
JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • When you use an Iterator to remove one or more elements in a collection, this is safe to do. When you use a for-each or for loop, removing is either not allowed or causes a bug because when removing while looping over the collection the indexes of each element in the collection changes. Therefore you should use a reverse for loop, or use an iterator to prevent introducing a bug. See also this [answer](http://stackoverflow.com/questions/223918/iterating-through-a-collection-avoiding-concurrentmodificationexception-when-re). – user504342 Apr 05 '16 at 09:53
  • 2
    that "ith" you said, is a challenge in English language. – M D P Oct 29 '16 at 06:42
  • 1
    Maybe he can replace it with "i-th"? – Miroslav Todorov Mar 13 '20 at 09:28
28

Iterator Advantage:

  • Ability to remove elements from Collections.
  • Ability to move forward and backward using next() and previous().
  • Ability to check if there more elements or not by using 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.

Salah
  • 8,567
  • 3
  • 26
  • 43
16

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.

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(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.

xburgos
  • 381
  • 3
  • 10
12

if you access to data by number (e.g. "i"), it is fast when you use array. because it goes to element directly

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.

if you use iterator, compiler knows that where you are. so It needs O(1) (because, it start from current position)

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

user3392677
  • 121
  • 4
  • So I should say it depends on the requirement. – rocking Mar 08 '14 at 10:19
  • +1 for pointing out the disadvantages of using a loop by index on Java `Collections`. It's worth pointing out that an enhanced for loop uses an `Iterator` under the hood. – Boris the Spider Mar 08 '14 at 10:20
  • 1
    Your other data structure examples aren't helpful - an ArrayList provides indexed access. Maybe update to include specific Java collections? (e.g. ArrayList vs LinkedList) – Richard Miskin Mar 08 '14 at 10:22
5

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 iterator solves 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.

This is from the book that it is https://www.amazon.com/Beginning-Algorithms-Simon-Harris/dp/0764596748

Zombies
  • 25,039
  • 43
  • 140
  • 225
fgul
  • 5,763
  • 2
  • 46
  • 32
1

I stumbled on this question. The answer lies to the problems Iterator tries to solve:

  • access and traverse the elements of an aggregate object without exposing its representation
  • define traversal operations for an aggregate object without changing its interface
Happy
  • 121
  • 1
  • 8