Using the forEach() Method to Iterate Over a Collection – Collections: Part II


Using the forEach() Method to Iterate Over a Collection

The default method forEach() of the Iterable<E> interface (which the Collection<E> interface implements) allows us to do away with an explicit iterator in order to perform an operation on each element of the collection. The method requires a consumer as the argument (§13.7, p. 709). The lambda expression defining the consumer is executed successively for each element of the collection.

In Example 15.1, the lambda expression passed as the argument at (8) prints each name in uppercase. Note that the method is invoked directly on the collection.

Click here to view code image

collectionOfNames.forEach(name ->
    System.out.print(name.toUpperCase() + ” “));                 // (8)

Filtering

We illustrate here two ways of filtering a collection—in this case, removing elements from the collection that satisfy certain criteria.

Using the remove() Method of an Iterator to Filter a Collection

Example 15.1 shows how an explicit iterator can be used in a loop to remove elements from a collection that fulfills certain criteria. As we have seen earlier, an explicit iterator is obtained at (9) and used in the loop at (10). The order of calls to the hasNext() and next() methods on the iterator at (10) and (11), respectively, ensures that each element in the underlying collection is retrieved in the loop. The call to the remove() method in the loop at (12) removes the current element from the underlying collection, if the criteria in the if statement is satisfied.

Click here to view code image

// [Alice, Bob, Tom, Dick, Harriet]
iterator = collectionOfNames.iterator();                         // (9)
while (iterator.hasNext()) {                                     // (10)
  String name = iterator.next();                                 // (11)
  if (name.length() == 3)
    iterator.remove();                                           // (12)
}
// [Alice, Dick, Harriet]

Best practices dictate that the three methods of the iterator should be used in lockstep inside a loop, as shown in Example 15.1. In particular, the next() method must be called before the remove() method for each element in the collection; otherwise, a java.lang.IllegalStateException or an UnsupportedOperationException is raised at runtime, depending on whether the collection provides this optional operation or not. As noted earlier, using an explicit iterator places the responsibility of bookkeeping on the user code.

Leave a Reply

Your email address will not be published. Required fields are marked *