Java 8 Features : forEach method

Java 8 popular features:

Some of the important Java 8 features are;

  • forEach() method in Iterable interface
  • default and static methods in Interfaces
  • Functional Interfaces and Lambda Expressions
  • Java Stream API for Bulk Data Operations on Collections
  • Java Time API
  • Collection API improvements
  • Concurrency API improvements
  • Java IO improvements
  • Miscellaneous Core API improvements

 

Let’s have a brief look on these Java 8 features. I will provide some code snippets for better understanding, so if you want to run programs in Java 8, you will have to setup Java 8 environment by following steps.

forEach() method in Iterable interface

Whenever we need to traverse through a Collection, we need to create an Iterator whose whole purpose is to iterate over and then we have business logic in a loop for each of the elements in the Collection. We might get ConcurrentModificationException if iterator is not used properly.

Java 8 has introduced forEach method in java.lang.Iterable interface so that while writing code we focus on business logic only. forEach method takes java.util.function.Consumer object as argument, so it helps in having our business logic at a separate location that we can reuse. Let’s see forEach usage with simple example.

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.function.Consumer;
import java.lang.Integer;
 
public class Java8ForEachExample {
 
     public static void main(String[] args) {
         
          //creating sample Collection
          List myList = new ArrayList();
          for(int i=0; i<10; i++) myList.add(i);
         
          //traversing using Iterator
          Iterator it = myList.iterator();
          while(it.hasNext()){
               Integer i = it.next();
               System.out.println("Iterator Value::"+i);
          }
         
          //traversing through forEach method of Iterable with anonymous class
          myList.forEach(new Consumer() {
 
               public void accept(Integer t) {
                     System.out.println("forEach anonymous class Value::"+t);
               }
 
          });
         
          //traversing with Consumer interface implementation
          MyConsumer action = new MyConsumer();
          myList.forEach(action);
         
     }
 
}
 
//Consumer implementation that can be reused
class MyConsumer implements Consumer{
 
     public void accept(Integer t) {
          System.out.println("Consumer impl Value::"+t);
     } 
}

The number of lines might increase but forEach method helps in having the logic for iteration and business logic at separate place resulting in higher separation of concern and cleaner code.

Overview

Introduced in Java 8, the forEach loop provides programmers with a new, concise and interesting way for iterating over a collection.

Basics of forEach
 

In Java, the Collection interface has Iterable as its super interface – and starting with Java 8 this interface has a new API:

void forEach(Consumer action)

Simply put, the Javadoc of forEach stats that it “performs the given action for each element of the Iterable until all elements have been processed or the action throws an exception.”

 

And so, with forEach, we can iterate over a collection and perform a given action on each element, like any other Iterator.

 

For instance, a for-loop version of iterating and printing a Collection of Strings:

 

for (String name : names) {
    System.out.println(name);
}

We can write this using forEach as:

names.forEach(name -> {     System.out.println(name); });

Using the forEach Method

We use forEach to iterate over a collection and perform a certain action on each element. The action to be performed is contained in a class that implements the Consumer interface and is passed to forEach as an argument.

 

The Consumer interface is a functional interface (an interface with a single abstract method). It accepts an input and returns no result.

 

Here’s the definition:

@FunctionalInterface
public interface Consumer {
    void accept(T t);
}
Therefore, any implementation, for instance, a consumer that simply prints a String:
Consumer printConsumer = new Consumer() {
public void accept(String name) {
System.out.println(name);
};
}; public void accept(String name) { System.out.println(name); }; };
can be passed to forEach as an argument:
names.forEach(printConsumer);

But that is not the only way of creating an action via a consumer and using forEach API.

 

Let’s see the 3 most popular ways in which we will use the forEach method:

 

3.1. Anonymous Consumer Implementation

 

We can instantiate an implementation of the Consumer interface using an anonymous class and then apply it as an argument to the forEach method:

 

Consumer printConsumer= new Consumer() {
public void accept(String name) {
System.out.println(name);
}
};
names.forEach(printConsumer); public void accept(String name) { System.out.println(name); } }; names.forEach(printConsumer);

Leave a Reply