Section 1.3. Foreach


1.3. Foreach

Here, again, is our code that computes the sum of a list of integers.

 List<Integer> ints = Arrays.asList(1,2,3); int s = 0; for (int n : ints) { s += n; } assert s == 6; 

The loop in the third line is called a foreach loop even though it is written with the keyword for. It is equivalent to the following:

 for (Iterator<Integer> it = ints.iterator(); it.hasNext(); ) {   int n = it.next();   s += n; } 

The emphasized code corresponds to what was written by the user, and the unemphasized code is added in a systematic way by the compiler. It introduces the variable it of type Iterator<Integer> to iterate over the list ints of type List<Integer>. In general, the compiler invents a new name that is guaranteed not to clash with any name already in the code. Note that unboxing occurs when the expression it.next() of type Integer is assigned to the variable n of type int.

The foreach loop can be applied to any object that implements the interface Iterable<E> (in package java.lang), which in turn refers to the interface Iterator<E> (in package java.util). These define the methods iterator, hasNext, and next, which are used by the translation of the foreach loop (iterators also have a method remove, which is not used by the translation):

 interface Iterable<E> {   public Iterator<E> iterator(); } interface Iterator<E> {   public boolean hasNext();   public E next();   public void remove(); } 

All collections, sets, and lists in the Collections Framework implement the Iterable<E> interface; and classes defined by other vendors or users may implement it as well.

The foreach loop may also be applied to an array:

 public static int sumArray(int[] a) {   int s = 0;   for (int n : a) { s += n; }   return s; } 

The foreach loop was deliberately kept simple and catches only the most common case. You need to explicitly introduce an iterator if you wish to use the remove method or to iterate over more than one list in parallel. Here is a method that removes negative elements from a list of doubles:

 public static void removeNegative(List<Double> v) {   for (Iterator<Double> it = v.iterator(); it.hasNext();) {     if (it.next() < 0) it.remove();   } } 

Here is a method to compute the dot product of two vectors, represented as lists of doubles, both of the same length. Given two vectors, u1,..., un and v1,..., vn, it computes u1 * v1 +...+ un * vn:

 public static double dot(List<Double> u, List<Double> v) {   if (u.size() != v.size())     throw new IllegalArgumentException("different sizes");   double d = 0;   Iterator<Double> uIt = u.iterator();   Iterator<Double> vIt = v.iterator();   while (uIt.hasNext()) {     assert uIt.hasNext() && vIt.hasNext();     d += uIt.next() * vIt.next();   }   assert !uIt.hasNext() && !vIt.hasNext();   return d; } 

Two iterators, uIt and vIt, advance across the lists u and v in lock step. The loop condition checks only the first iterator, but the assertions confirm that we could have used the second iterator instead, since we previously tested both lists to confirm that they have the same length.




Java Generics and Collections
Java Generics and Collections
ISBN: 0596527756
EAN: 2147483647
Year: 2006
Pages: 136

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net