Professional Documents
Culture Documents
Using Foreach Loops in J2SE 1
Using Foreach Loops in J2SE 1
Using Foreach Loops in J2SE 1
Like many Java developers you are probably working with the beta for J2SE 1.5. Here
is another new technique to use with the beta. Looping through a collection of objects
and doing something with each object is one of the most common programming
idioms. You've no doubt coded such a loop many times:
If you were to use an array, this is how you would typically iterate through each of its
elements:
It's not difficult to iterate through a collection, but it is a very repetitive operation.
Iteration requires you to type a good amount of characters. Granted, the template
feature of most IDEs will eliminate your need to type so much. But, as you saw, there
are many ways to iterate through a loop.
The existence of several different iteration techniques costs you more time. For each
iteration you encounter, you must spend a few extra seconds digesting the iteration
form. If it deviates from the form you're used to seeing, you must examine it even
closer. Why did the developer choose to code the iteration differently?
It's also easy to make a mistake in coding your iterator. Ever accidentally coded
something like this?
Effective use of the foreach loop depends on using Java 1.5's parameterized types,
also known as generics. So that you can understand the code in this article, I'll
explain how to use parameterized types.
Here is how you might construct and iterate a list of names in Java 1.5:
To construct an object of the parameterized ArrayList type, you bind the ArrayList to a
class. In the example, you bind the ArrayList to the String class. You also bind the List
reference to the String class. You are now restricted to adding only String objects to
the list. If you insert, for example, a Date object in the names collection, your code
will not compile. When you retrieve objects from the list, you need not cast. Java
knows that the list contains only String objects. It does the casting for you, behind
the scenes.
Once you have stored objects in a parameterized List, you can iterate through them
using the foreach loop:
The foreach loop is succinct. There is no need to cast; Java does the cast for you. You
can use the name reference within the body of the loop as a String reference. You
cannot use the name reference outside the body of the foreach loop.
You saw how the foreach loop allows you to iterate over collection class types. Sun
also modified Java to allow you to iterate through arrays using foreach. The syntax is
exactly the same:
import java.util.*;
class Catalog {
private List<Product> products = new ArrayList<Product>();
void add(Product product) {
products.add(product);
}
}
The Product class includes a method that allows you to discount the price on a
product:
class Product {
private String id;
private String name;
private BigDecimal cost;
Product(String id, String name, BigDecimal cost) {
this.id = id;
this.name = name;
this.cost = cost;
}
A (Poor) Solution
To allow client code to work with all products, you could create a method in Catalog
that returned the ArrayList of products:
// don't do this
List<Product> getProducts() {
return products;
}
Client code could iterate through the list however they chose. However, returning a
collection to a client is a bad idea. By giving the client your collection, you have
relinquished any control over the contents of that collection. Client code could add or
remove elements to the collection without the knowledge of the Catalog object.
You've also burdened the client with more work than necessary.
package java.lang;
import java.util.Iterator;
public interface Iterable<T> {
Iterator<T> iterator();
}
To implement this interface in Catalog, you must code an iterator method. This
method must return an Iterator object that is bound to the Product type.
The Catalog class stores all of its Product objects in an ArrayList. The easiest way to
provide an Iterator object to a client is to simply return the Iterator object from the
products ArrayList itself. Here is the modified Catalog class:
Once you have implemented the java.lang.Iterable interface, client code can use the
foreach loop. Here is a bit of example code:
Summary
The foreach loop provides a simple, consistent solution for iterating arrays, collection
classes, and even your own collections. It eliminates much of the repetitive code that
you would otherwise require. The foreach loop eliminates the need for casting as well
as some potential problems. The foreach loop is a nice new addition to Java that was
long overdue. I greatly appreciate the added simplicity in my source code.