Get a Sight of Functional Programming in Java

Isurie K. Liyanage
5 min readAug 14, 2021

Functional programming is a programming paradigm where programs are created by applying and combining functions. This enables us to write programs in a declarative and composable way, where small functions are combined in a modular way. Rightly, functional programming is all about expressions introduced in Java 8. Functional techniques improve java programming by making us think functionally about cording tasks.

This article may help you become familiar with functional programming in a simple and easy-to-understand manner.

In Java 8, a new feature was introduced called lambdas. Lambdas represent the implementation of a functional interface.

Functional Interfaces

A functional interface is an interface that has only one abstract method. The following code snippet shows a simple interface called GreetingMessage. The interface has a single abstract method called greet which takes one argument of type string called name. The annotation functionalInterface has been added above the name of the interface to show that it conforms to the rules of a functional interface.

Implement the functional interface in another class:

Here inside the main method, a new instance of GreetingMessage called gm is equal to the new GreetinMessage instance. we override the greeting method as GreetingMessage has an abstract method with no implementation. we have to add our own implementation every time we create a new instance of GreetingMessage . This is also known as an anonymous inner class.

The method can be called by gm.greet("name") , passing a name. This outputs hello with the name given.

That is all the functional interface is. It allows Java Programmers to pass the code around as data. The code to implement our functional interface is quite long and messy considering that all it does is provide one new line of functionality. Lambda is introduced to improve this.

Implementing lambdas in java

Lambdas provide a short and simple way to implement a functional interface in Java. They are now commonly used features in the Java language.

Here there is a functional interface called GreetingMessage which has a single abstract method called greet. In the Main class a new GreetingMessage an instance is implemented using an anonymous inner class. The GreetingMessage and print out hello followed by the name passed in.

Instead of using all this boilerplate code, we can use lambda instead to make the code shorter and simpler.

We also can just put the name in here. Here we get the same outputs for both implementations. we use the lambda with less code. we didn’t need to create a new greeting message or write out the whole body of the method again.

For example, let’s take functional interface MessagePrinter which has a single abstract method, called printMessage which takes no arguments.

In main method of the Main class,

This outputs our message. So lambdas are a quick and simple way of implementing functional interfaces, they look quite different to anonymous inner classes, but the logic is the same and it is easy to understand when we are used to reading the syntax.

Using method references in java

Method reference is shortened way of writing a certain type of lambda expression. If you have a lambda expression that passes in a variable and then calls a method on that variable, you can replace it with a method reference.

In this example, there is a class called Square. This class has one private field of type int called sideLength and public calculate area method, which calculates the area by multiplying sideLength by sideLength. The constructor of the Square class specifies that we have to pass in an int for the sideLengt value.

A functional interface called shapes is there. This has a single abstract method called get area.

In main method of the Main class,

When run the program shows the area as 16(4*4). Let's use a method reference to make this code shorter and simpler. we can do this because we are using lambda for calling a single method on the square object that we are passing in.

This also prints out the area of the square is 16. This is shorter and simple than the lambda.

Understanding streams in Java

Streams provide a clean and simple way to iterate over a collection in Java. Instead of using a forEach loop, streams allow functional programming techniques to be used. These streams are not to be confused with input and output streams which are something completely different.

For example, the forEach loop iterates over a collection of books. If the author of the book’s name begins with the letter J, then the two-string method of the book is called and printed to the terminal. Here it uses external iteration.

Issues of External Iteration:

  1. Hard to write parallel iterations
  2. Requires a lot of boilerplate codes to write.
  3. Difficult to read the meaning.
  4. There is no much abstraction between the code and the implementation.

Streams, which are introduced in Java 8, provide solutions to these issues. Streams work differently to forLoops. They use internal iteration instead of external iteration.

we can rewrite forEach loop to use a stream to iterate over the collection of books.

The first method called stream() returns a stream object. This is an interface that contains a sequence of elements from the collection we called the method on. It contains book objects from the books list.

Then the filter() method, Streams have two different types of methods, lazy methods, and eager methods. Here we are using the filter() method as an example of lazy method. The only thing this method does is checks if the author begins with J, and if it does, then it adds it to the stream.

Finally, there is the forEach method, which is an eager method. This prints out all of the objects in the stream. So instead of creating an iterator object, which a forEach loop does, it creates a stream object. For each item, if the author begins with “J”, then it adds that item to the stream. It doesn’t print out the book straightway, instead, it waits till the end when it has a stream of all the books whose author begins with “J”. Then it prints out that stream.

If we want to add more filters, we would change them to the end of the first one.

This is much simpler to read than forEach loop, where we need to add a new nested if statement for each condition. It is also more computationally efficient to use this approach.

Implementing streams in java

Book.java

Library.java

Implementing parallel streams

Here the only thing that needs to change in the code is to change the stream method to the parallel stream method.

Here I have included code-embedded which I used in understanding each scenario for your reference.

Thanks for reading, follow me to see more articles..

--

--

Isurie K. Liyanage

Technical Writer | BSc. (Hons.) IT — UoM | Software Engineer