Tino APCS

Iterators and For-Each Loops

Iterators

An Iterator is an object that can be attached to any type of Collection object. Since an ArrayList is a type of Collection, you can use an Iterator to traverse an ArrayList from first to last element. Doing so is easier and safer than using a classic for-loop because an Iterator keeps track of where it is in the list even if we are adding and removing from it.

Consider the code below:

ArrayList <String> names = new ArrayList <String>();
names.add("George");
names.add("Nancy");
names.add("John");
names.add("John");
names.add("Bill");
names.add("Maria");

// Remove anyone named "John"
for (int i = 0; i < names.size(); i++)
    if (names.get(i).equals("John"))
        names.remove(i);

// Print the revised list
for (int i = 0; i < names.size(); i++)
    System.out.println(names.get(i));


There is a problem with this code. Can you identify the problem? Spend a few minutes thinking about the problem and come up with a way to fix it using the same loop structure and code as given above. The required bug fix is small but critical.

See Answer Below 1

A much more elegant solution is available using Iterators. Since Iterator objects keep track of the items in a Collection for you, you do not need to worry about the index counter skipping past items. In fact, you do not even need an index counter! Read the API (java.util.Iterator) and then study the code below. It does the same thing as the code shown above but uses an Iterator to traverse the list of names:

Iterator<String> iter = names.iterator();

// Remove anyone named "John"
while(iter.hasNext())
    if (iter.next().equals("John"))
        iter.remove();


Iterators are invaluable when using advanced Data Structures (see the AB curriculum). Even so, you should consider using them in your code from now on because they are are a clean way run through an ArrayList or other type of Collection even when the contents of the Collection change.

For-Each Loops

As long as you don't need to modify the contents of a Collection, there is a new and simpler type of loop structure that came with the release of Java 5. The AP Exam uses it extensively and you will therefore need to know it and use it.

It's called a For-Each loop and here's the syntax:

Collection b;

for (Object a : b)
    a.whatever();


The loop reads as follows: "for each Object a in b ... do a.whatever()". This simplifies your code greatly as you do not need a loop counter. The for-each loop automatically steps through your Collection of objects and returns the next object for you to use at will.

Here is an example using classic for loops.

// suits is an ArrayList of Suit objects
// faces is an ArrayList of Face objects
// cards is an ArrayList of Card objects

for(int i = 0; i < faces.size(); i++)
  for(int j = 0; i < suits.size(); j++)
      cards.add(new Card(faces.get(i), suits.get(j)));


And here is the for-each version. Much better!

for(Face f: faces)
  for(Suit s: suits)
      cards.add(new Card(f, s));


The code reads smoothly:

for each Face object in faces, do...
    for each Suit object in suits, do...


For more examples, search the Web for "Java for-each loop". Know it, use it, love it. The for-each loop!


  1. When the first occurance of "John" is found it is deleted from the ArrayList. No problem there. However, the loop counter should not be incremented when an item is deleted because doing effectively skips over the next item. Trace this code by hand and you'll see it happen before your eyes. You will find that the second instance of "John" is never checked because the loop counter skips right past it.

    To fix this, you need to prevent the counter from incrementing when an item is deleted:

    if (names.get(i).equals("John"))
       names.remove(i--);  // Decrementing keeps the counter where it belongs 
    

    go back 

Last modified: November 14, 2023

Back to The Wrapper Classes

Dark Mode

Outline