Reputation: 15052
The question might be pretty vague I know. But the reason I ask this is because the class must have been made with some thought in mind.
This question came into my mind while browsing through a few questions here on SO.
Consider the following code:
class A
{
private int myVar;
A(int varAsArg)
{
myVar = varAsArg;
}
public static void main(String args[])
{
List<A> myList = new LinkedList<A>();
myList.add(new A(1));
myList.add(new A(2));
myList.add(new A(3));
//I can iterate manually like this:
for(A obj : myList)
System.out.println(obj.myVar);
//Or I can use an Iterator as well:
for(Iterator<A> i = myList.iterator(); i.hasNext();)
{
A obj = i.next();
System.out.println(obj.myVar);
}
}
}
So as you can see from the above code, I have a substitute for iterating using a for
loop, whereas, I could do the same using the Iterator
class' hasNext()
and next()
method. Similarly there can be an example for the remove()
method. And the experienced users had commented on the other answers to use the Iterator
class instead of using the for
loop to iterate through the List
. Why?
What confuses me even more is that the Iterator
class has only three methods. And the functionality of those can be achieved with writing a little different code as well.
Some people might argue that the functionality of many classes can be achieved by writing one's own code instead of using the class
made for the purpose. Yes,true. But as I said, Iterator
class has only three methods. So why go through the hassle of creating an extra class when the same job can be done with a simple block of code which is not way too complicated to understand either.
EDIT:
While I'm at it, since many of the answers say that I can't achieve the remove functionality without using Iterator
,I would just like to know if the following is wrong, or will it have some undesirable result.
for(A obj : myList)
{
if(obj.myVar == 1)
myList.remove(obj);
}
Doesn't the above code snippet do the same thing as remove()
?
Upvotes: 4
Views: 890
Reputation: 1
I think answer to your question is abstraction. Iterator is written because to abstract iterating over different set of collections.
Every collection has different methods to iterate over their elements. ArrayList has indexed access. Queues has poll and peek methods. Stack has pop and peek.
Usually you only need to iterate over elements so Iterator comes into play. You do not care about which type of Collection you need to iterate. You only call iterator() method and user Iterator object itself to do this.
If you ask why not put same methods on Collection interface and get rid of extra object creation. You need to know your current position in collection so you can not implement next method in Collection because you can not use it on different locations because every time you call next() method it will increment index (simplifying every collection has different implementation) so you will skip some objects if you use same collection at different places. Also if collection support concurrency than you can not write a multi-thread safe next() method in collection.
It is usually not safe to remove an object from collection iterating by other means than iterator. Iterator.remove() method is safest way to do it. For ArrayList example: for(int i=0;i
Upvotes: 0
Reputation: 500357
First of all, the for-each construct actually uses the Iterator
interface under the covers. It does not, however, expose the underlying Iterator
instance to user code, so you can't call methods on it.
This means that there are some things that require explicit use of the Iterator
interface, and cannot be achieved by using a for-each loop.
Removing the current element is one such use case.
For other ideas, see the ListIterator
interface. It is a bidirectional iterator that supports inserting elements and changing the element under the cursor. None of this can be done with a for-each loop.
for(A obj : myList) { if(obj.myVar == 1) myList.remove(obj); }
Doesn't the above code snippet do the same thing as remove() ?
No, it does not. All standard containers that I know of will throw ConcurrentModificationException
when you try to do this. Even if it were allowed to work, it is ambiguous (what if obj
appears in the list twice?) and inefficient (for linked lists, it would require linear instead of constant time).
Upvotes: 3
Reputation: 1944
Iterator is an implementation of the classical GoF design pattern. In that way you can achieve clear behaviour separation from the 'technical code' which iterates (the Iterator) and your business code.
Imagine you have to change the 'next' behaviour (say, by getting not the next element but the next EVEN element). If you rely only on for
loops you will have to change manually every single for loop, in a way like this
for (int i; i < list.size(); i = i+2)
while if you use an Iterator you can simply override/rewrite the "next()" and "hasNext()" methods and the change will be visible everywhere in your application.
Upvotes: 0
Reputation: 116266
For one thing, Iterator
was created way before the foreach loop (shown in your code sample above) was introduced into Java. (The former came in Java2, the latter only in Java5).
Since Java5, indeed the foreach loop is the preferred idiom for the most common scenario (when you are iterating through a single Iterable
at a time, in the default order, and do not need to remove or index elements). Note though that the foreach uses an iterator in the background for standard collection classes; in other words it is just syntactic sugar.
Upvotes: 2
Reputation: 2121
The foreach construct (for (X x: list)
) actually uses Iterator
as its implementation internally. You can feed it any Iterable
as a source of elements.
And, as others already remarked: Iterator is longer in Java than foreach, and it provides remove()
.
Also: how else would you implement your own provider class (myList
in your example)? You make it Iterable
and implement a method that creates an Iterator
.
Upvotes: 3
Reputation: 1530
Iterator, listIterator both are used to allow different permission to user, like list iterator have 9 methods but iterator have only 3 methods, but have remove functionality which you can't achieve with for loop. Enumeration is another thing which is also used to give only read permissions.
Upvotes: 1
Reputation: 19443
Iterator
came long before the for
statement that you show in the evolution of Java. So that's why it's there. Also if you want to remove something, using Iterator.remove()
is the only way you can do it (you can't use the for
statement for that).
Upvotes: 7