Java 8 forEach

Introduction

Java 8 introduced the forEach() method, which allows us to iterate over elements in a collection in a concise and functional manner. The forEach() method is part of the Iterable interface and is also available in streams, making it an efficient and flexible way to loop through collections like ArrayList, Set, and Map.

In this tutorial, we'll explore how to use the forEach() method with various data structures, including lists, maps, and streams. We'll also demonstrate a real-world example of converting entities into DTOs using forEach().

Table of Contents

  • Example 1: Using forEach() with an ArrayList
  • Example 2: Using forEach() with a Map
  • Example 3: Using forEach() with a Stream
  • Example 4: Using forEach() with a Custom Action (Lambda Expressions)
  • Example 5: Using Method References with forEach()
  • Example 6: Real-Time Example: Mapping Entities to DTOs

Example 1: Using forEach() with an ArrayList

The most common use case of forEach() is with ArrayList or other list implementations. You can iterate over each element in the list and perform an action on each element.

Code Example

import java.util.ArrayList;

public class ForEachArrayListExample {
    public static void main(String[] args) {
        // Creating an ArrayList of Strings
        ArrayList<String> cities = new ArrayList<>();
        cities.add("Mumbai");
        cities.add("Delhi");
        cities.add("Bangalore");
        cities.add("Chennai");

        // Iterating over the ArrayList using forEach()
        cities.forEach(city -> System.out.println(city));
    }
}

Output

Mumbai
Delhi
Bangalore
Chennai

Explanation

  • The forEach() method is called on the cities ArrayList.
  • A lambda expression (city -> System.out.println(city)) defines the action to perform on each element (printing the city name).
  • This is a functional and concise alternative to traditional loops.

Example 2: Using forEach() with a Map

The forEach() method can also be used with Map objects. When working with maps, you can use forEach() to process both keys and values.

Code Example

import java.util.HashMap;
import java.util.Map;

public class ForEachMapExample {
    public static void main(String[] args) {
        // Creating a HashMap of city and population
        Map<String, Integer> cityPopulation = new HashMap<>();
        cityPopulation.put("Mumbai", 20411000);
        cityPopulation.put("Delhi", 16787941);
        cityPopulation.put("Bangalore", 8443675);

        // Iterating over the HashMap using forEach()
        cityPopulation.forEach((city, population) -> 
            System.out.println(city + " has a population of " + population));
    }
}

Output

Mumbai has a population of 20411000
Delhi has a population of 16787941
Bangalore has a population of 8443675

Explanation

  • The forEach() method processes each entry in the Map, taking both the key (city) and value (population) as parameters.
  • The lambda expression allows us to define an action on both the key and value (printing the city and its population).

Example 3: Using forEach() with a Stream

The forEach() method is also commonly used in streams. When working with streams, forEach() can be used to perform an action on each element of the stream.

Code Example

import java.util.Arrays;
import java.util.List;

public class ForEachStreamExample {
    public static void main(String[] args) {
        // Creating a list of numbers
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

        // Using forEach() on a Stream
        numbers.stream().forEach(number -> System.out.println(number * 2));
    }
}

Output

2
4
6
8
10

Explanation

  • We create a stream from the numbers list using numbers.stream().
  • The forEach() method is used to process each element in the stream, multiplying each number by 2 and printing the result.
  • This approach is concise and takes advantage of Java 8's functional programming.

Example 4: Using forEach() with a Custom Action (Lambda Expressions)

The forEach() method allows you to define custom actions using lambda expressions. This makes the method very flexible, enabling a wide range of operations.

Code Example

import java.util.Arrays;
import java.util.List;

public class ForEachCustomActionExample {
    public static void main(String[] args) {
        // Creating a list of names
        List<String> names = Arrays.asList("Amit", "Deepa", "Rahul", "Suresh");

        // Using forEach() with a custom action
        names.forEach(name -> {
            if (name.startsWith("A")) {
                System.out.println(name + " starts with A");
            }
        });
    }
}

Output

Amit starts with A

Explanation

  • We use a lambda expression to define a custom action where we check if the name starts with "A".
  • If the condition is true, we print a message.

Example 5: Using Method References with forEach()

Java 8 allows you to use method references with forEach() to make the code even more concise. A method reference is a shorthand for a lambda expression.

Code Example

import java.util.Arrays;
import java.util.List;

public class ForEachMethodReferenceExample {
    public static void main(String[] args) {
        // Creating a list of languages
        List<String> languages = Arrays.asList("Java", "Python", "C++", "Go");

        // Using forEach() with a method reference
        languages.forEach(System.out::println);
    }
}

Output

Java
Python
C++
Go

Explanation

  • Instead of using a lambda expression, we use a method reference (System.out::println), which is shorthand for x -> System.out.println(x).
  • The forEach() method prints each element of the list using the method reference.

Example 6: Real-Time Example: Mapping Entities to DTOs

In real-world scenarios, it's common to convert entities into DTOs (Data Transfer Objects). The following example demonstrates how to use forEach() to map a list of Entity objects to EntityDTO objects.

Code Example

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class ForEachRealTimeExamples {

    public static void main(String[] args) {
        List<Entity> entities = getEntities();

        List<EntityDTO> dtos = new ArrayList<>();
        // Mapping Entity to EntityDTO using forEach()
        entities.forEach(entity -> {
            dtos.add(new EntityDTO(entity.getId(), entity.getEntityName()));
        });

        // Displaying EntityDTO details
        dtos.forEach(e -> {
            System.out.println(e.getId());
            System.out.println(e.getEntityName());
        });
    }

    // Simulating the retrieval of entities
    public static List<Entity> getEntities() {
        List<Entity> entities = new ArrayList<>();
        entities.add(new Entity(100, "entity 1"));
        entities.add(new Entity(100, "entity 2"));
        entities.add(new Entity(100, "entity 3"));
        return entities;
    }
}

class EntityDTO {
    private int id;
    private String entityName;
    private Date createdAt;
    private String createBy;
    private Date updatedAt;
    private String updatedBy;

    public EntityDTO(int id, String entityName) {
        this.id = id;
        this.entityName = entityName;
    }

    // Getters and setters
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getEntityName() {
        return entityName;
    }

    public void setEntityName(String entityName) {
        this.entityName = entityName;
    }
}

class Entity {
    private int id;
    private String entityName;
    private Date createdAt;
    private String createBy;
    private Date updatedAt;
    private String updatedBy;

    public Entity(int id, String entityName) {
        this.id = id;
        this.entityName = entityName;
        this.createdAt = new Date();
        this.createBy = "ramesh";
        this.updatedAt = new Date();
        this.updatedBy = "ramesh";
    }

    // Getters and setters
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getEntityName() {
        return entityName;
    }

    public void setEntityName(String entityName) {
        this.entityName = entityName;
    }
}

Output

100
entity 1
100
entity 2
100
entity 3

Explanation

  • We simulate a process where entities are retrieved and converted into DTOs using the forEach() method.
  • This real-time example demonstrates how forEach() can be applied in enterprise applications to streamline object transformations.

Conclusion

The forEach() method in Java 8 is a powerful and flexible way to iterate over collections and streams. It allows for concise iteration using lambda expressions or method references. Whether you're working with ArrayList, Map, or streams, forEach() simplifies iteration and opens up possibilities for functional programming in Java. The real-time example of mapping entities to DTOs shows the practical use of this method in enterprise-level applications.

Comments