Last Modified 2019.3.4

Functional programming in Java 8

Since Java 8, Java supports functional programming. If the parameter type of a method is a functional interface, a lambda expression or a method reference can be substituted for it. A functional interface is an interface that has only one abstract method. Lambda expressions and method references are discussed later.

Create movies.txt file as follows and copy it to the /src directory.

Butch Cassidy And The Sundance Kid,1969,8.1
Lucy,2014,6.4
Asphalte,2015,7.1
Spy,2015,7.0
Blade Runner 2049,2017,8.1
Small Town Crime,2017,6.6
The Commuter,2018,6.3
Flashdance,1983,6.1
Midnight Run,1988,7.6
Twelve Monkeys,1995,8.0
As Good As It Gets,1997,7.7
Collateral,2004,7.5
Choke,2008,6.5
The Dark Knight,2008,9.0
The Dark Knight Rises,2012,8.4
Infinitely Polar Bear,2014,7.0
Mission Impossible 3,2006,6.9
Mission Impossible 4,2011,7.4
The Terminator,1984,8.0
Terminator 2,1991,8.5
Flight,2012,7.3
Our Brand Is Crisis,2015,6.1
The Rewrite,2014,6.2
The Secret Life of Walter Mitty,2013,7.3
Waterloo Bridge,1940,7.8
Roman Holiday,1953,8.1
Ben Hur,1959,8.1
The Battle of Algiers,1966,8.1
Love Story,1970,6.9
Jaws,1975,8.0
Operation Daybreak,1975,7.1
Blade Runner,1982,8.2
The Silence Of The Lambs,1991,8.6
Thelma and Louise,1991,7.4
Scent of a Woman,1992,8.0
The Shawshank Redemption,1994,9.3
Heat,1995,8.2
Jerry Maguire,1996,7.6
Knockin On Heavens Door,1997,8.0
28 Days,2000,6.0
Unbreakable,2000,7.3
Secondhand Lion,2003,7.6
Eternal Sunshine of the Spotless Mind,2004,8.3
Little Miss Sunshine,2006,7.8
No Country for Old Men,2007,8.1
The Lookout,2007,7.0
Doubt,2008,7.5
The Bank Job,2008,7.3
The Wrestler,2008,7.9
Agora,2009,7.2
Morning Glory,2010,6.5
Foxfire,2012,6.2
Drive,2011,7.8
Walk of Shame,2014,6.0
Truth,2015,6.8
Tschick,2016,7.0
Creed,2015,7.6
Rocky,1976,8.1

Create a movie class as shown below.

package net.java_school.examples;

public class Movie {
	private final String title;
	private final int releaseDate;
	private final double userRatings;

	public Movie(String title, int releaseDate, double userRatings) {
		this.title = title;
		this.releaseDate = releaseDate;
		this.userRatings = userRatings;
	}

	public String getTitle() {
		return title;
	}

	public int getReleaseDate() {
		return releaseDate;
	}

	public double getUserRatings() {
		return userRatings;
	}

	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder();
		sb.append(this.getTitle());
		sb.append(",");
		sb.append(this.getReleaseDate());
		sb.append(",");
		sb.append(this.getUserRatings());

		return sb.toString();
	}

}

title indicates the movie title, releaseDate indicates the release date, and userRatings indicates the user rating.

Create a functional interface like this:

package net.java_school.examples;

public interface Predicate<T> {
	boolean test(T t);
}

Predicate is a function that takes a value and returns true or false. Create a class that implements the Predicate functional interface as follows:

package net.java_school.examples;

public class Rated8OrAbovePredicate implements Predicate<Movie> {

	@Override
	public boolean test(Movie movie) {
		return movie.getUserRatings() >= 8.0;
	}

}

Create a class for testing as follows:

package net.java_school.examples;

import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;

public class MovieTest {

	static List<Movie> filterMovies(List<Movie> movies, Predicate<Movie> p) {
		List<Movie> result = new ArrayList<>();
		for (Movie movie : movies) {
			if (p.test(movie)) {
				result.add(movie);
			}
		}

		return result;
	}

	public static void main(String[] args) throws Exception {
		String fileName = "./src/movies.txt";
		String str = null;
		List<Movie> movies = new ArrayList<>();

		try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {
			while ((str = br.readLine()) != null) {
				String[] arr = str.split(",");
				Movie movie = new Movie(arr[0], Integer.parseInt(arr[1]), Double.parseDouble(arr[2]));
				movies.add(movie);
			}
		}

		List<Movie> result = filterMovies(movies, new Rated8OrAbovePredicate());

		for (Movie movie : result) {
			System.out.println(movie);
		}

	}

}
Butch Cassidy And The Sundance Kid,1969,8.1
Blade Runner 2049,2017,8.1
Twelve Monkeys,1995,8.0
The Dark Knight,2008,9.0
The Dark Knight Rises,2012,8.4
The Terminator,1984,8.0
Terminator 2,1991,8.5
Roman Holiday,1953,8.1
Ben Hur,1959,8.1
The Battle of Algiers,1966,8.1
Jaws,1975,8.0
Blade Runner,1982,8.2
The Silence Of The Lambs,1991,8.6
Scent of a Woman,1992,8.0
The Shawshank Redemption,1994,9.3
Heat,1995,8.2
Knockin On Heavens Door,1997,8.0
Eternal Sunshine of the Spotless Mind,2004,8.3
No Country for Old Men,2007,8.1
Rocky,1976,8.1

Compare the result with the original movie.txt. The result is highlighted.

Butch Cassidy And The Sundance Kid,1969,8.1
Lucy,2014,6.4
Asphalte,2015,7.1
Spy,2015,7.0
Blade Runner 2049,2017,8.1
Small Town Crime,2017,6.6
The Commuter,2018,6.3
Flashdance,1983,6.1
Midnight Run,1988,7.6
Twelve Monkeys,1995,8.0
As Good As It Gets,1997,7.7
Collateral,2004,7.5
Choke,2008,6.5
The Dark Knight,2008,9.0
The Dark Knight Rises,2012,8.4
Infinitely Polar Bear,2014,7.0
Mission Impossible 3,2006,6.9
Mission Impossible 4,2011,7.4
The Terminator,1984,8.0
Terminator 2,1991,8.5
Flight,2012,7.3
Our Brand Is Crisis,2015,6.1
The Rewrite,2014,6.2
The Secret Life of Walter Mitty,2013,7.3
Waterloo Bridge,1940,7.8
Roman Holiday,1953,8.1
Ben Hur,1959,8.1
The Battle of Algiers,1966,8.1
Love Story,1970,6.9
Jaws,1975,8.0
Operation Daybreak,1975,7.1
Blade Runner,1982,8.2
The Silence Of The Lambs,1991,8.6
Thelma and Louise,1991,7.4
Scent of a Woman,1992,8.0
The Shawshank Redemption,1994,9.3
Heat,1995,8.2
Jerry Maguire,1996,7.6
Knockin On Heavens Door,1997,8.0
28 Days,2000,6.0
Unbreakable,2000,7.3
Secondhand Lion,2003,7.6
Eternal Sunshine of the Spotless Mind,2004,8.3
Little Miss Sunshine,2006,7.8
No Country for Old Men,2007,8.1
The Lookout,2007,7.0
Doubt,2008,7.5
The Bank Job,2008,7.3
The Wrestler,2008,7.9
Agora,2009,7.2
Morning Glory,2010,6.5
Foxfire,2012,6.2
Drive,2011,7.8
Walk of Shame,2014,6.0
Truth,2015,6.8
Tschick,2016,7.0
Creed,2015,7.6
Rocky,1976,8.1

So far, this is about Java 7.

In Java 8, you can instantiate a functional interface with a lambda expression. In MovieTest's main method, you can get the same result by modifying the List<Movie> result = filterMovies(movies, new Rated8OrAbovePredicate()) statement as below:

List<Movie> result = filterMovies(movies, (Movie movie) -> movie.getUserRatings() >= 8.0);

A lambda expression instance is not created from Rated8OrAbovePredicate. To verify, delete the class Rated8OrAbovePredicate and test again.

Since Java 8, a functional interface like Predicate has been added to the API. Add the Predicate interface of the API to the import statement, delete the Predicate interface we created, and test again.

import java.util.function.Predicate;

An instance of a functional interface can also be created as a method reference. Add the following method to Movie.java to test the method reference.

public static boolean isPopular(Movie movie) {
	return movie.getUserRatings() >= 8.0;
}

In MovieTest's main method, modify
List<Movie> result = filterMovies(movies, (Movie movie) -> movie.getUserRatings() >= 8.0);
to
List<Movie> result = filterMovies(movies, Movie::isPopular); and test again.

Java 8 provides a number of functional interfaces that can be used in a variety of situations in the java.util.function package. Functional interfaces are classified into three categories: Predicate, Consumer, and Function.

java.util.function.Consumer<T> interface defines an accept abstract method that accepts a generic T object and returns void.

java.util.function.Function<T,R> interface defines an apply abstract method that accepts a generic T abject and return generic R.

A functional interface acts as a signature of a lambda expression or method reference.

The Predicate interface provides the default methods: negate(), and(), or(). Add the negate() default method as shown below and test again.

Predicate<Movie> popularMovies = Movie::isPopular;
List<Movie> result = filterMovies(movies, popularMovies.negate());
Lucy,2014,6.4
Asphalte,2015,7.1
Spy,2015,7.0
Small Town Crime,2017,6.6
The Commuter,2018,6.3
Flashdance,1983,6.1
Midnight Run,1988,7.6
As Good As It Gets,1997,7.7
Collateral,2004,7.5
Choke,2008,6.5
Infinitely Polar Bear,2014,7.0
Mission Impossible 3,2006,6.9
Mission Impossible 4,2011,7.4
Flight,2012,7.3
Our Brand Is Crisis,2015,6.1
The Rewrite,2014,6.2
The Secret Life of Walter Mitty,2013,7.3
Waterloo Bridge,1940,7.8
Love Story,1970,6.9
Operation Daybreak,1975,7.1
Thelma and Louise,1991,7.4
Jerry Maguire,1996,7.6
28 Days,2000,6.0
Unbreakable,2000,7.3
Secondhand Lion,2003,7.6
Little Miss Sunshine,2006,7.8
The Lookout,2007,7.0
Doubt,2008,7.5
The Bank Job,2008,7.3
The Wrestler,2008,7.9
Agora,2009,7.2
Morning Glory,2010,6.5
Foxfire,2012,6.2
Drive,2011,7.8
Walk of Shame,2014,6.0
Truth,2015,6.8
Tschick,2016,7.0
Creed,2015,7.6

Add the and() default method as shown below and test again.

Predicate<Movie> popularMovies = Movie::isPopular;
List<Movie> result = filterMovies(movies, popularMovies.negate().and(m -> m.getReleaseDate() > 2015));
Small Town Crime,2017,6.6
The Commuter,2018,6.3
Tschick,2016,7.0

Because of type inference, (Movie m) -> m.getReleaseDate() > 2015 can be abbreviated to m -> m.getReleaseDate() > 2015.

Final source : https://github.com/kimjonghoon/functionalProgramming

How to run

~/functionalProgramming$ cd src/net/java_school/examples/
~/functionalProgramming/src/net/java_school/examples$ javac -d ../../../../bin *.java
~/functionalProgramming/src/net/java_school/examples$ cd -
~/functionalProgramming$ java -cp ./bin net.java_school.examples.MovieTest
Small Town Crime,2017,6.6
The Commuter,2018,6.3
Tschick,2016,7.0