views:

676

answers:

5

Hi, When I use an Iterator of Object I use a while loop (as written in every book learning Java, as Thinking in Java of Bruce Eckel):

Iterator it=...

while(it.hasNext()){
    //...
}

but sometime i saw than instead somebody use the for loop:

Iterator it=...
for (Iterator it=...; it.hasNext();;){
    //...
}

I dont' understand this choice:

  • I use the for loop when I have a collection with ordinal sequence (as array) or with a special rule for the step (declared generally as a simple increment counter++).
  • I use the while loop when the loop finish with I have'nt this constraints but only a logic condition for exit.

It's a question of style-coding without other cause or it exists some other logic (perfomance, for example) that I dont' know?

Thanks for every feedback

+6  A: 

It's just a style thing and like you I prefer the for loop when using something with an index. If you're using Java 5 you should of course use a foreach loop over the collection anyway:

Collection<String> someCollection = someCollectionOfString();
for (String element : someCollection) {
....
}
MrWiggles
The only thing you lose by using this form of iterator is that you can't call the Iterator.remove() method - since you have no reference to the Iterator object.
Bill Michell
True.. but you're gonna find that out pretty damn quick!
MrWiggles
+10  A: 

The correct syntax for the for loop is:

for (Iterator it = ...; it.hasNext(); ){
    //...
}

(The preceding declaration in your code is superfluous, as well as the extra semicolon in the for loop heading.)

Whether you use this syntax or the while loop is a matter of taste, both translate to exactly the same. The generic syntax of the for loop is:

for (<init stmt>; <loop cond>; <iterate stmt>) { <body>; }

which is equivalent to:

<init stmt>;
while (<loop cond>) { <body>; <iterate stmt>; }

Edit: Actually, the above two forms are not entirely equivalent, if (as in the question) the variable is declared with the init statement. In this case, there will be a difference in the scope of the iterator variable. With the for loop, the scope is limited to the loop itself, in the case of the while loop, however, the scope extends to the end of the enclosing block (no big surprise, since the declaration is outside the loop).

Also, as others have pointed out, in newer versions of Java, there is a shorthand notation for the for loop:

for (Iterator<Foo> it = myIterable.iterator(); it.hasNext(); ) {
    Foo foo = it.next();
    //...
}

can be written as:

for (Foo foo : myIterable) {
    //...
}

With this form, you of course lose the direct reference to the iterator, which is necessary, for example, if you want to delete items from the collection while iterating.

David Hanak
If you add in the references to limited scope gained from using a "for" loop this becomes the perfect answer...
Michael Rutherfurd
@Michael: There you go.
David Hanak
A: 

People may use the explicit ('old style') for loop simply because it feels cleaner to them, perhaps they haven't adjusted to the new syntax yet (which I personally think is a lot cleaner).

One actual specific advantage of the longer for loop construct is that you have a reference to the iterator and so can call methods on it other then next(). In particular, hasNext() can often be useful to call - imagine if you want to print out a list of strings comma-separated:

StringBuilder sb = new StringBuilder();
for (Iterator it=...; it.hasNext();){
   sb.append(it.next());
   if (it.hasNext())
      sb.append(", ");
}

It is only to distinguish the "this is the last one" case like this if you use the more verbose for loop.

Andrzej Doyle
+2  A: 

There isn't much difference between those two methods, other than the first one remembers the value of it after the loop. The second approach probably throws an error, because you redeclare the variable inside the loop.

There's actually a third method to this, aswell. Instead of writing e.g.

for (Iterator<SomeObject> it = foo.iterator(); it.hasNext();) {
  SomeObject so = foo.next();
}

you can most often write

for (SomeObject so: foo) {...}

These two equal to the same thing...

Henrik Paul
+3  A: 

The purpose of declaring the Iterator within the for loop is to minimize the scope of your variables, which is a good practice.

When you declare the Iterator outside of the loop, then the reference is still valid / alive after the loop completes. 99.99% of the time, you don't need to continue to use the Iterator once the loop completes, so such a style can lead to bugs like this:

//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
}
matt b