Monday, September 28, 2015

forEach() method in Iterable interface and Stream interface in Java 8

To iterate a collection, we have several ways:

  • Using Normal for loop
  • Using Enhanced for loop
  • Using Iterator (java.util.Iterator)
1. Using Normal for loop:
List<String> names = new ArrayList<>();
names.add("Ranga");
names.add("Reddy");
names.add("Raja");
names.add("Vasu");
        
System.out.println("Using normal for loop..");
for(int index = 0; index < names.size(); index++) {
    System.out.println(names.get(index));
}
2. Using Enhanced for loop:
System.out.println("\nUsing enhanced for loop..");
for(String name: names) {
    System.out.println(name);
}
3. Using Iterator (java.util.Iterator):
System.out.println("\nUsing Iteraotr..");
Iterator<String> namesIterator = names.iterator();
while(namesIterator.hasNext()) {
    System.out.println(namesIterator.next());
}

In java 8, a new method is introduced to iterate collection ie. forEach(). This forEach() is defined in two places namely, inside java.lang.Iterable interface and java.util.stream.Stream interface.
4. Using Iterable (java.lang.Iterable):
Collection classes that implements Iterable interface (List, Set) have a default method called a forEach(), it takes one argument i.e Consumer functional interface.
package java.lang;

public interface Iterable<T> {
    --------
    default void forEach(Consumer<? super T> action) {
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }
   --------
}
System.out.println("\nUsing Consumer..");
Consumer<String> namesConsumer = (name) -> System.out.println(name);                 
names.forEach(namesConsumer);
5. Using Streams (java.util.Stream):
Same as Iterable interface forEach() stream interface also having one forEach() method it will take Consumer functional interface. Through streams, we can iterate collection (List, Set, Map) values serial and parallel.
package java.util.stream;
public interface Stream<T> extends BaseStream<T, Stream<T>> {
    --------
    void forEach(Consumer<? super T> action);
    --------
}
System.out.println("\nUsing Stream forEach..");                  
names.stream().forEach((name) -> System.out.println(name));
        
System.out.println("\nUsing Parallel Stream forEach..");                     
names.parallelStream().forEach((name) -> System.out.println(name));
If you we use parallelStream().forEach() method, there is no guarantee to which order elements will display. To make same order we need to use forEachOrdered() method.

Note: Instead of using Iterable forEach() method prefer to use Streams().forEach() because streams are lazy and not evaluated until a terminal operation is called.
package com.ranga.foreach;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author Ranga Reddy
 * @version 1.0
 */
public class ForEachDemo {
    public static void main(String[] args) {
                
        List<String> names = new ArrayList<>();
        names.add("Ranga");
        names.add("Reddy");
        names.add("Raja");
        names.add("Vasu");
        
        System.out.println("\nPrinting the list values using forEach()..");              
        names.stream().forEach((name) -> System.out.println(name));
        
        
        System.out.println("\nPrinting the set values using forEach()..");
        Set<String> setNames = new HashSet<>(names);
        setNames.add("Ranga");
        setNames.forEach(System.out::println);
        
        Map<String, String> namesMap = new HashMap<>();
        namesMap.put("name1", "Ranga");
        namesMap.put("name2", "Reddy");
        namesMap.put("name3", "Vasu");
        namesMap.put("name4", "Raja");
        
        System.out.println("\nPrinting the hashmap values using forEach()..");
        namesMap.forEach((key, value) -> System.out.println("Key: "+key +", Value: "+value));
    }
}
Output:
Printing the list values using forEach()..
Ranga
Reddy
Raja
Vasu

Printing the set values using forEach()..
Raja
Reddy
Vasu
Ranga

Printing the hashmap values using forEach()..
Key: name4, Value: Raja
Key: name3, Value: Vasu
Key: name2, Value: Reddy
Key: name1, Value: Ranga

0 comments: