Java forEach – Java 8 forEach

Filed Under: Java

Java forEach method was introduced in Iterable interface in Java 8. Java 8 forEach method is another way that we can use to traverse through a collection.

Java forEach

java forEach, java 8 forEach, java foreach example, java 8 foreach example
Below code snippet shows the default implementation of java forEach method in Iterable interface. Read java 8 interface changes to learn more about default interface methods.


default void forEach(Consumer<? super T> action) {
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }

Java forEach method performs the given action for each element of the Iterable until all elements have been processed or exception is thrown.

Java 8 forEach List Example

Before java 8, We could iterate over a list by using for loop or iterator.


List<String> list = getList();
		
//prior to java 8
//using enhanced for loop
for(String s : list){
	System.out.println(s);
}

//using iterator
Iterator<String> it = list.iterator();
while(it.hasNext()){
	System.out.println(it.next());
}

Now same thing can be performed using java forEach method as shown below.


// Create Consumer instance
Consumer<String> action = new Consumer<String>(){

	@Override
	public void accept(String t) {
		System.out.println(t);
	}
	
};

//java 8 forEach
list.forEach(action);

Since Consumer is a functional interface, we can use lambda expression and write above code in one line as;


list.forEach(k -> {System.out.println(k);});

Java 8 forEach Map Example

Prior to java 8, we iterate over Map elements like below.


Map<Integer,String> map = getMap();

//iteration prior to java 8
Set<Integer> keySet = map.keySet();

//using enhanced for loop
for (Integer i : keySet){
	System.out.println(map.get(i));
}

//using iterator
Iterator<Integer> it = keySet.iterator();
while(it.hasNext()){
	System.out.println(map.get(it.next()));
}

Since Map doesn’t extend Iterable, forEach method is added into Map interface in java 8 and below shows the default implementation.


default void forEach(BiConsumer<? super K, ? super V> action) {
        Objects.requireNonNull(action);
        for (Map.Entry<K, V> entry : entrySet()) {
            K k;
            V v;
            try {
                k = entry.getKey();
                v = entry.getValue();
            } catch(IllegalStateException ise) {
                // this usually means the entry is no longer in the map.
                throw new ConcurrentModificationException(ise);
            }
            action.accept(k, v);
        }
    }

Let’s look at a simple example how we can use java 8 forEach with Map.


BiConsumer<Integer,String> action = new BiConsumer<Integer, String>(){

	@Override
	public void accept(Integer t, String u) {
		System.out.println(u);
	}
	
};
//java 8 forEach with Map
map.forEach(action);

Same code can be written using lambda expressions as below.


map.forEach((k,v) -> {System.out.println(v);});

Java forEach Benefits

I don’t see too much benefit of forEach loop except when you are using it with parallel stream. A new method was added in Collection interface to get the parallel stream.


default Stream<E> parallelStream() {
        return StreamSupport.stream(spliterator(), true);
    }

So if we have to iterate over a collection and we are not bothered about sequential iteration, then we can use parallel stream with forEach loop as shown below.


//parallel operation using stream
list.parallelStream().forEach(action);

That’s all for Java forEach method. I hope you will find some use case for java 8 forEach method in parallel processing.

Comments

  1. Avik Dutta says:

    Any comment on the following simple bench marking:
    public class Test {

    public static void main(String[] args) {
    List list = new ArrayList();
    for (int i = 0; i {
    function(i);
    });
    System.out.println((System.currentTimeMillis() – time));

    time = System.currentTimeMillis();
    list.parallelStream().forEach(i -> {
    function(i);
    });
    System.out.println((System.currentTimeMillis() – time));
    }

    private static void function(int i) {
    i = i * 9 + 90 – 23 + i / 4;
    }

    }
    Output::
    23
    57
    43

    Clearly shows the traditional forEach loop gives better performance (in terms of time duration of processing) than others, even the parallelStream one.

Comments are closed.

close
Generic selectors
Exact matches only
Search in title
Search in content