2

Every For Loop with an Iterator that i've ever used (to use the Iterator.remove(); method) looks like this:

for (Iterator<E> iter = list.iterator(); iter.hasNext(); ) {
    E element = iter.next();
    //some code
}

Basic For Loops are styled:

for([initial statement]; [loop condition]; [iterating statement]) {/*Some Code*/}

So my question is... why are they never written

for (Iterator<E> iter = list.iterator(); iter.hasNext(); E element = iter.next()) {
    //some code
}
Oliver
  • 893
  • 6
  • 5

3 Answers3

6

The for loop grammar does not permit you to declare a variable in the "iterating statement".

(You can declare one in the "initial statement" which is why for (Iterator<E> iter = list.iterator(); iter.hasNext(); ) is syntatically valid.)

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
6

The iterating statement executes after the loop body has executed. In other words, when you write the following:

for (Iterator<E> iter = list.iterator(); iter.hasNext(); element = iter.next()) {
   //some code
}

element = iter.next() would run after the body has run for each iteration, so if you are printing the element, for example, the first element would be whatever initial value element had.

Example:

List<String> list = new ArrayList<String>();
list.add("a1");
list.add("a2");
list.add("a3");
for (Iterator<String> iterator = list.iterator(); iterator.hasNext();) {
    String string =  iterator.next();
    System.out.println(string);
}

Output:

a1
a2
a3

With the iter.next() in the for loop:

List<String> list = new ArrayList<String>();
list.add("a1");
list.add("a2");
list.add("a3");
String string = null;
for (Iterator<String> iterator = list.iterator(); iterator.hasNext(); string = iterator.next()) {
    System.out.println(string);
}

Output:

null
a1
a2

P.S.: The loop as you declared (for (Iterator<E> iter = list.iterator(); iter.hasNext(); E element = iter.next()) will not compile, so you would need to declare element as a variable before this line.

M A
  • 71,713
  • 13
  • 134
  • 174
-1

Given that a for loop is just syntactic sugar around a while loop, and you cannot use the "iterating statement" the way you want, it might be neater to use a while loop directly:

Iterator<E> iter = list.iterator();
while (iter.hasNext()) {
  E element = iter.next();
  //some code
}
weston
  • 54,145
  • 21
  • 145
  • 203
  • It's best practice to minimize the scope of local variables. – Puce Dec 02 '14 at 13:17
  • It's better than before but still not minimized. The minimal scope in this case is the scope of the loop, if you don't need the variable outside of the loop. – Puce Dec 02 '14 at 13:41
  • @Puce I think readability is more important than "best practice" rules on scoping. Look at this question, I'd say this method is the most commonly used. http://stackoverflow.com/a/1196612/360211 – weston Dec 02 '14 at 14:05
  • I agree that readability is more important, but I find this version less readable since my eyes have to check more scopes. If I see such a variable outside the loop scope I start to wonder if it is used outside that scope and for what reason. If in the end it isn't used at all outside the loop scope then it's a check I wouldn't have needed to do if the scope of the variable has been minimized. Maybe it's just me. – Puce Dec 02 '14 at 14:42
  • @Puce Looked a bit further, I think both ways are pretty common http://stackoverflow.com/a/223929/360211 – weston Dec 02 '14 at 14:46
  • I know that it is quite common, but that doesn't make it better. I see it every now and then at code reviews. – Puce Dec 02 '14 at 14:48
  • @Puce Maybe your methods are too long. Mine are 4-5 lines max. Any more lines and it's doing too much and can refactored into smaller methods. This example, would definitely be in it's own method. So no question about what `iter` is used for outside the loop. It will always be in a pretty short scope in good SRP code. – weston Dec 02 '14 at 14:48