Replacing your foreach loops with the Java 8 Streams API

I wanted to make a quick post about the Java 8 streams API. It’s really cool. I mainly use it to simplify foreach loops.

Isn’t this:

Much nicer like this?

In Java 8, the Collection interface includes the stream method. This returns a Stream of the collection. It allows you to specify a chain of sequential operations to be executed for each of its members, using a fluent API that allows you to format the code much more functionally than before.

Both of the previous blocks of code do the same thing:

  1. Check if the account is overdrawn
  2. If so, fetch the corresponding customer object from the customer database
  3. Check if the customer is a premium customer
  4. If so, write an entry to the log

First, on line 4, we filter the stream with a boolean check. If the check returns true, the account object qualifies and it passes to the next method in the chain. Account::isOverdrawn is an example of a method reference. In this context, the filter checks the result of account.isOverdrawn(). Method references are a type of lambda expression. The imperative style of traditional Java can produce code which is overly verbose, the preceding foreach loop being a good example. Lambda expressions are a way of writing certain programming constructs succinctly and in a functional paradigm, and any Java programmer who values easy-to-read code should familiarise themselves with it if they haven’t already.

On line 5, we define a mapping from Accounts to Customers. The stream changes type from one to the other. Another method reference is used, this time to refer to a method belonging to another object: customerDatabase.get(Account account). This method takes a single argument, which map fills with the account object coming from up the stream. The Customer object that returns from the method invocation is passed down to the next method in the chain.

On line 6, we filter the stream of Customers to exclude any premium customers. This is an example of a lambda expression. We could use a method reference if not for the fact that we want the reverse of the result from that method. Since we need to perform two operations — calling isPremium() and then negating the result — a full lambda expression is required.

On line 7, we finally write the entry to the log with another lambda expression.

Leave a Comment

Your email address will not be published. Required fields are marked *