Java 8 Foreach() Method

The forEach function in Java 8 offers a simple approach for iterating through collections, bringing functional programming concepts closer to Java developers. It belongs to the Iterable interface and accepts a Consumer functional interface as a parameter. By leveraging this method, programmers can write more succinct code without the need for the verbose boilerplate code typically found in traditional loops. Classes that implement the Iterable interface can utilize the forEach loop for traversing elements.

The function accepts a functional interface as its sole parameter, allowing us to provide a lambda expression as input.

forEach Signature in Iterable Interface

Example

default void forEach(Consumer<super T>action)

When the keyword "default" is used, it signifies that the method has a default implementation within the interface. Java 8 introduced default methods to tackle the problem of interface method default implementations causing disruptions in existing code.

Return type in a method signifies the type of value that the method will return. In this case, the forEach method does not return any value; instead, it performs an operation on every element within the collection.

The method is called forEach, indicating that it operates like a loop where each item in the collection is utilized to perform a particular task.

(The <? super T> action): This section defines the parameter for the method. The parameter is of type Consumer, which is an interface located in the java.util.function package. A functional interface is a type of interface that contains only a single abstract method. The Consumer interface signifies an operation that takes a single input but does not produce any output.

In the input parameter, 'T' signifies the category of items within the compilation. The <? Firstly, a supertype bound allows the consumer to interpret any superclass of T provided, which makes the types of actions one can do on the elements flexible.

Advantages Over the Traditional Loops

  • A key advantage of forEach over the typical loops is its compactness and comprehension. While lambda expressions are used to contain iteration logic, it helps reduce the thinking burden on the developers thus making code easy to comprehend and maintain.
  • Also, forEach enhances a more functional way of coding by the fact of mutability and the separation of the aspects. This strategy matches the current software engineering practices, enabling creation of more neat, modular code.
  • Java 8 forEach Example 1

ForEachExample.java

ForEachExample.java

Output:

Output

default void forEach(Consumer<super T>action)

Java 8 forEach Example 2

ForEachExample.java

Example

import java.util.ArrayList;

import java.util.List;

public class ForEachExample {

    public static void main(String[] args) {

        List<String> gamesList = new ArrayList<String>(); // Creating a new ArrayList to store games

        // Adding games to the list

        gamesList.add("Football");

        gamesList.add("Cricket");

        gamesList.add("Chess");

        gamesList.add("Hockey");

        // Printing a separator

        System.out.println("------------Iterating by passing lambda expression--------------");

        // Iterating over the list using forEach and printing each element using a lambda expression

        gamesList.forEach(game -> System.out.println(game));

    }

}

Output:

Output

------------Iterating by passing lambda expression--------------

Football

Cricket

Chess

Hocky

Java Stream forEachOrdered Method

The forEachOrdered method in Java streams is similar to the forEach method. It executes a provided action on each element of the stream in the encounter order. However, unlike forEach, which allows for unordered parallel execution, forEachOrdered guarantees that the elements are processed in the order specified by the stream.

Singnature:

Example

import java.util.ArrayList;

import java.util.List;

public class ForEachExample {

    public static void main(String[] args) {

        List<String> gamesList = new ArrayList<String>(); // Creating a new ArrayList to store games

        // Adding games to the list

        gamesList.add("Football");

        gamesList.add("Cricket");

        gamesList.add("Chess");

        gamesList.add("Hockey");

        // Printing a separator

        System.out.println("------------Iterating by passing method reference---------------");

        // Iterating over the list using forEach and printing each element using method reference

        gamesList.forEach(System.out::println);

    }

}

(Consumer<? super T> function) serves as the argument for the forEachOrdered function. It requires a Consumer functional interface instance.

The consumer is a functional interface that is specified in the java.util.function package. It characterizes a function that takes one input and does not produce any output.

<? super T> is a placeholder that enables the Consumer to receive any superclass of T, offering versatility in the kinds of operations that can be executed on the elements within the stream.

"Action" refers to the parameter that signifies the specific operation to be executed on every element within the stream. It is determined by the user at the time of calling the forEachOrdered method.

The method commonly employs streams to handle elements from each stream and maintain the original sequence of occurrences. It serves as a highly efficient logical operator for organized streams or managing sequences where the order is crucial.

Encounter Sequence: In the context of streams, the encounter sequence refers to the manner in which stream elements are met during processing. When dealing with ordered streams, such as those derived from lists and arrays, the encounter sequence mirrors the iteration sequence of the source collection. Conversely, for unordered streams or those generated from sets, the encounter sequence may be unspecified or non-repetitive.

In the realm of streams, there is a distinction between Sequential and Parallel Streams. The method forEachOrdered ensures that the operation will be executed on each element based on their order of encounter, regardless of whether it is executed in parallel. It is important to note that while forEach enables a more relaxed parallel execution where the order of elements is not guaranteed, a for loop guarantees a logically sequential execution.

Java Stream forEachOrdered Method Example

Java Stream forEachOrdered Method Example

Example

import java.util.ArrayList;

import java.util.List;

public class ForEachOrderedExample {

	public static void main(String[] args) {

		List<String> gamesList = new ArrayList<String>();

		gamesList.add("Football");

		gamesList.add("Cricket");

		gamesList.add("Chess");

		gamesList.add("Hocky");

		System.out.println("------------Iterating by passing lambda expression---------------");

		gamesList.stream().forEachOrdered(games -> System.out.println(games));

		System.out.println("------------Iterating by passing method reference---------------");

		gamesList.stream().forEachOrdered(System.out::println);

	}



}

Output:

Output

------------Iterating by passing lambda expression---------------

Football

Cricket

Chess

Hocky

------------Iterating by passing method reference---------------

Football

Cricket

Chess

Hocky

Input Required

This code uses input(). Please provide values below: