Java 8 – Stream forEachOrdered() method

In this article, we will discuss Stream’s forEachOrdered() method which is used to iterate through stream elements in the encounter order, irrespective of whether the stream is sequential or parallel

Encounter order :-

  • The order in which stream elements are supplied
  • For example, if the original source to stream is ArrayList which preserves insertion order, then stream follows insertion order of ArrayList

1. Stream forEachOrdered() method :

  • This Stream method is a terminal operation which is used to iterate through all elements present in the Stream in the encounter order
  • Performs an action for each element of this stream, in the encounter order of the stream if the stream has a defined encounter order
  • Input to the forEachOrdered() method is Consumer which is Functional Interface
  • Irrespective of whether Stream is Sequential or Parallel, this method iterates through all elements in the encounter order, if one such exists i.e.; as stream elements supplied to forEachOrdered method
  • forEachOrdered() method is non-interfering with other elements in the Stream
  • Method signature :- void forEachOrdered(Consumer<? super T> action)

1.1 Stream forEachOrdered() method example :

  • Here, we will take a look at an example for forEachOrdered() method of Stream API
  • We will iterate through all elements present using forEachOrdered method after obtaining Sequential stream as well as Parallel stream
  • Also, we will note time difference for processing in Sequential & Parallel order which is 20 ms & 14 ms respectively
  • Another thing to note here is that, elements in List are printed as per original insertion order in both Sequential & Parallel stream
  • Note :- we will use method reference for printing to console
package net.bench.resources.stream.foreachordered.example;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;

public class ForEachOrderedExample {

	public static void main(String[] args) {

		LocalDateTime startLocalDateTime = null;
		LocalDateTime endLocalDateTime = null;
		Duration duration = null;

		// create List of String elements
		List<String> names = Arrays.asList(
				"Vijay",
				"Ajith",
				"Kamal",
				"Rajini",
				"Dhanush",
				"Simbhu",
				"Surya",
				"Vikram",
				"Arya",
				"Vishal"
				);


		System.out.println("1. Names in the original List in LOWER CASE :- \n\n"
				+ names);

		// SEQUENTIAL - convert names to Upper case and print to console
		System.out.println("\n\n2. Names after UPPER CASE conversion"
				+ " in forEachOrdered SEQUENTIAL processing :- \n");

		// get start time
		startLocalDateTime = LocalDateTime.now();

		names // original source
		.stream() // 1. get SEQUENTIAL stream from source
		.map(name -> name.toUpperCase()) // 2. map intermediate operation
		.forEachOrdered(System.out::println); // 3. forEachOrdered terminal operation

		// get end time after sequential processing
		endLocalDateTime = LocalDateTime.now();
		duration = Duration.between(startLocalDateTime, endLocalDateTime);
		System.out.println("\nTime difference in Milliseconds"
				+ " after SEQUENTIAL processing = " + duration.toMillis() + " ms");


		// PARALLEL - convert names to Upper case and print to console
		System.out.println("\n\n3. Names after UPPER CASE conversion"
				+ " in forEachOrdered PARALLEL processing :- \n");

		// get start time
		startLocalDateTime = LocalDateTime.now();

		names // original source
		.parallelStream() // 1. get PARALLEL stream from source
		.map(name -> name.toUpperCase()) // 2. map intermediate operation
		.forEachOrdered(System.out::println); // 3. forEachOrdered terminal operation

		// get end time after parallel processing
		endLocalDateTime = LocalDateTime.now();
		duration = Duration.between(startLocalDateTime, endLocalDateTime);
		System.out.println("\nTime difference in Milliseconds"
				+ " after PARALLEL processing = " + duration.toMillis() + " ms");
	}
}

Output:

1. Names in the original List in LOWER CASE :- 

[Vijay, Ajith, Kamal, Rajini, Dhanush, Simbhu, Surya, Vikram, Arya, Vishal]


2. Names after UPPER CASE conversion in forEachOrdered SEQUENTIAL processing :- 

VIJAY
AJITH
KAMAL
RAJINI
DHANUSH
SIMBHU
SURYA
VIKRAM
ARYA
VISHAL

Time difference in Milliseconds after SEQUENTIAL processing = 15 ms


3. Names after UPPER CASE conversion in forEachOrdered PARALLEL processing :- 

VIJAY
AJITH
KAMAL
RAJINI
DHANUSH
SIMBHU
SURYA
VIKRAM
ARYA
VISHAL

Time difference in Milliseconds after PARALLEL processing = 12 ms

1.2 forEach() v/s forEachOrdered() methods in parallel stream :

  • To understand the capability of forEachOrdered() method, first we need to take a look at forEach() method
  • forEach() method processes as stream elements are supplied to it
  • For Sequential stream, it will processes/iterates/print as per the order it receives which is of course sequential in nature same as that of original order and took 16 ms to complete its process
  • While for Parallel stream, forEach() method doesn’t guarantee encounter order (or insertion order for List) and stream elements might get processed/iterated/printed in different order but took just 7 ms to complete its process
  • We will understand above points with an example, as coded below
package net.bench.resources.stream.foreachordered.example;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;

public class ForEachVsForEachOrdered {

	public static void main(String[] args) {

		LocalDateTime startLocalDateTime = null;
		LocalDateTime endLocalDateTime = null;
		Duration duration = null;

		// create List of String elements
		List<String> names = Arrays.asList(
				"Vijay",
				"Ajith",
				"Kamal",
				"Rajini",
				"Dhanush",
				"Simbhu",
				"Surya",
				"Vikram",
				"Arya",
				"Vishal"
				);


		System.out.println("1. Names in the original List in LOWER CASE :- \n\n"
				+ names);

		// SEQUENTIAL - convert names to Upper case and print to console
		System.out.println("\n\n2. Names after UPPER CASE conversion"
				+ " in forEach SEQUENTIAL processing :- \n");

		// get start time
		startLocalDateTime = LocalDateTime.now();

		names // original source
		.stream() // 1. get SEQUENTIAL stream from source
		.map(name -> name.toUpperCase()) // 2. map intermediate operation
		.forEach(System.out::println); // 3. forEach terminal operation

		// get end time after sequential processing
		endLocalDateTime = LocalDateTime.now();
		duration = Duration.between(startLocalDateTime, endLocalDateTime);
		System.out.println("\nTime difference in Milliseconds"
				+ " after SEQUENTIAL processing = " + duration.toMillis() + " ms");


		// PARALLEL - convert names to Upper case and print to console
		System.out.println("\n\n3. Names after UPPER CASE conversion"
				+ " in forEach PARALLEL processing :- \n");

		// get start time
		startLocalDateTime = LocalDateTime.now();

		names // original source
		.parallelStream() // 1. get PARALLEL stream from source
		.map(name -> name.toUpperCase()) // 2. map intermediate operation
		.forEach(System.out::println); // 3. forEach terminal operation

		// get end time after parallel processing
		endLocalDateTime = LocalDateTime.now();
		duration = Duration.between(startLocalDateTime, endLocalDateTime);
		System.out.println("\nTime difference in Milliseconds"
				+ " after PARALLEL processing = " + duration.toMillis() + " ms");
	}
}

Output:

1. Names in the original List in LOWER CASE :- 

[Vijay, Ajith, Kamal, Rajini, Dhanush, Simbhu, Surya, Vikram, Arya, Vishal]


2. Names after UPPER CASE conversion in forEach SEQUENTIAL processing :- 

VIJAY
AJITH
KAMAL
RAJINI
DHANUSH
SIMBHU
SURYA
VIKRAM
ARYA
VISHAL

Time difference in Milliseconds after SEQUENTIAL processing = 16 ms


3. Names after UPPER CASE conversion in forEach PARALLEL processing :- 

SURYA
SIMBHU
ARYA
VIJAY
VISHAL
VIKRAM
RAJINI
KAMAL
DHANUSH
AJITH

Time difference in Milliseconds after PARALLEL processing = 7 ms

References:

Happy Coding !!
Happy Learning !!

Java 8 - Sorting List of primitive, String & Custom Objects
Java 8 - How to remove duplicates from ArrayList