Looping is certainly not new to Java 8, but you can tighten up your code quite a bit with the forEach expression.

And cleaner code is better, right?

In this article, we’ll go over how to use forEach in your code as a substitute for one of the old for expressions. As is usually the case, you can view the complete source code on GitHub.

 

Use Case

The use case here is that you’re running an e-commerce site that sells saltwater fishing tackle. One of the requirements is that you need to print out the list of customers.

Each customer is represented by a Customer class. Here’s what that class looks like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
public class Customer {
 
    private Long id;
    private String firstName;
    private String lastName;
    private Integer age;
 
     
    public Customer(Long id, String firstName, String lastName, Integer age) {
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
    }
     
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getFirstName() {
        return firstName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
     
    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append(lastName);
        builder.append(", ");
        builder.append(firstName);
        builder.append(" Age: ");
        builder.append(age);
        builder.append(" [ID=");
        builder.append(id);
        builder.append("]");
         
        return builder.toString();
    }
}

As you can see, it’s nothing too complicated. It’s a Java bean that follows the standard conventions.

Pay particular attention to the toString() method at the end. That’s the code that will display relevant info about the object in a user-friendly format.

 

The Old Way

In the old, pre-Java 8 days, you’d probably iterate through a List of objects with something like this:

1
2
3
for (Customer customer : customers) {
    System.out.println(customer);
}

Okay, that works. But wouldn’t you like something a little shorter and cleaner?

Why, yes. Yes you would.

Of course, you could also us an Iterator. That won’t save you any lines, though.

Finally, you could use an old-fashioned for…next loop based on the size of the List object. Once again, though, that doesn’t save you any space.

Let’s look at a better way.

 

ForEach With a Lambda Expression

A lambda expression gives you a way to represent a method interface in a single expression. There are many ways that you can use it, but here you’re going to use it with a forEach loop.

Let’s refactor the code above with a forEach loop that uses a lambda expression.

1
customers.forEach(customer->System.out.println(customer));

Boom. That’s quite a bit shorter, isn’t it?

Of course, that’s simplistic. Lambda expressions can handle more complicated logic as well.

For example: what if you wanted to only print out customers who are older than 25 years of age? Here’s how you would do that:

1
2
3
4
5
customers.forEach(customer -> {
    if (customer.getAge() > 25) {
        System.out.println(customer);
    }
});

There you go. If you need even more complicated logic, you can put it between the outer braces.

 

ForEach With a Method Reference

Believe it or not, you can tighten up the code above even more. For that, you need a method reference.

A method reference is a kissing cousin to a lambda expression. It’s often the case that the two are used together.

That’s what you’ll do here. Here’s the code from two blocks above refactored with a method reference.

1
customers.forEach(System.out::println);

Yep. That’s it.

The code infers that you want to print out each Customer object in the list based on that notation. You don’t have to reference a single object. You don’t even have to name a variable.

Java 8 figures it all out for you.

Here’s the whole code that demonstrates the different methods we’ve seen:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public class PrintCustomers {
 
    public static final void main(String[] args) {
        //get the list of customers
        List<Customer> customers = getCustomers();
         
        //let's print out all customers
        System.out.println("Printing all customers");
        customers.forEach(customer->System.out.println(customer));
         
        //let's print customers over the age of 25
        System.out.println("\nPrinting all customers over the age of 25");
        customers.forEach(customer -> {
            if (customer.getAge() > 25) {
                System.out.println(customer);
            }
        });
         
        System.out.println("\nPrinting all customers with a method reference");
        customers.forEach(System.out::println);
    }
     
     
    private static List<Customer> getCustomers() {
        List<Customer> customers = new ArrayList<Customer>();
         
        customers.add(new Customer(1000l,"John","Smith",25));
        customers.add(new Customer(1001l,"Jane","Doe",36));
        customers.add(new Customer(1002l,"Jerry","Tyne",20));
        customers.add(new Customer(1003l,"Glenn","First",29));
        customers.add(new Customer(1004l,"Beth","Abbey",35));
 
        return customers;
    }
}

The output of that code will look like this:

Printing all customers
Smith, John Age: 25 [ID=1000]
Doe, Jane Age: 36 [ID=1001]
Tyne, Jerry Age: 20 [ID=1002]
First, Glenn Age: 29 [ID=1003]
Abbey, Beth Age: 35 [ID=1004]

 

Printing all customers over the age of 25
Doe, Jane Age: 36 [ID=1001]
First, Glenn Age: 29 [ID=1003]
Abbey, Beth Age: 35 [ID=1004]

Printing all customers with a method reference
Smith, John Age: 25 [ID=1000]
Doe, Jane Age: 36 [ID=1001]
Tyne, Jerry Age: 20 [ID=1002]
First, Glenn Age: 29 [ID=1003]
Abbey, Beth Age: 35 [ID=1004]

 

Wrapping It Up

Here’s a challenge: try to use forEach with a Map. Take the code to the next level by making it as tight as possible.

If you want to see the code here in action, feel free to check it out on GitHub. You can clone the URI in your own Eclipse workspace and run the Java application yourself.

Have fun!