5 Things You Haven’t Heard about Java Functional Programming

Oh Java, our one true love! If ever there is a program that has revolutionized the course of our world, then Java would receive top honors. But let’s get away from our steamy love affair and get down to business. We can begin with the basics of java code helper first then get down to where all the magic happens. So what is Java functional programming?

Definition of Java Functional Programming

In the field of computer science, functional programming refers to a unique programming style; whereby a programmer builds up the structures and elements of a computer program from scratch. These structures and elements then treat and handle computation as a form of evaluating mathematical functions and do not change state or have mutating (big) data.

Let’s take an example. Below is a lambda expression.

x -> x + 1

The expression takes up an argument (x) and proceeds to increment it by one. That is to say, it is a function that receives the integer and then returns a new integer that has been incremented by one.

So what type of function would this execute in Java? Well, that depends on a lot of factors. For starters, a similar lambda expression in Java could be tied to different variables of a different type. For example, below are two credible declarations and string functions in Java:

Function<Integer,Integer> add1 = x -> x + 1;
Function<String,String> concat = x -> x + 1;

The first statement increments the integer present (x) by one while the other concatenates the integer (in this case 1) to any string x. Pretty interesting right? I know you’re probably scratching your head and going ‘huh’? How does one know how to invoke these functions at the right time? Well, it’s simple. Because they are tied to a specific reference, we can treat them the same way we treat any object in Java. Let’s show you further:

Integer two = add1.apply(1); //yields 2
String answer = concat1.apply("0 + 1 = "); //yields "0 + 1 = 1"

So as you can observe, every function can have a method apply that we can utilize to invoke on and pass it as a specific argument. But wait a minute. What if I’ve already got a method that does this? And all I want to do is to utilize it as a given function? Is this possible? Yes, it is. Since there is an alternative way to create functions through the use of methods, which can then be deemed compatible with our function defined. For example, suppose that we have a class definition with the given methods as demonstrated below:

public class Utils {
publicstatic Integer add1(Integer x) { return x + 1; }
publicstatic String concat1(String x) { return x + 1; }
}

As can be observed, the methods within this class are compatible with our initial and original function definitions; thus, we can just utilize them as ‘method references’ to recreate a similar function as we did initially with our lambda expressions. Observe and try them out:

Function<Integer,Integer> add1 = Utils::add1;
Function<String,String> concat1 = Utils::concat1;

What did you find? Aren’t the two similar to what we had done initially? Before we go any further with this example, a little sidenote. If you want to dive deeper into the world of functional programming and learn everything in details, here’s a handy book by Dean Wampler that can help you out.

Functional Programming for Java Developers

Java 8 Function Breakdown

Now let’s take it up a notch. We are going to dig deeper into Java functional programming by focusing on some of its unique features. Excited right? So am I! So let’s get started. Here are the top 5 things you haven’t heard about Java 8 functional programming.

1.Higher Order Programming

If you’re new to Java or have been round the game for quite for some time, one thing you notice is how awesome functions are! They can do just about everything because of one special feature. They can mimic behaviour. Basically, that means you can take a given section of a code, place it in a given function, and kick it around to other functions for them to utilize. These type of genius functions are known as high order functions. And the process of utilizing this unique feature is known as higher order programming. It can primarily be split into two.

2. Functions That Curate Other Functions

Let’s start with an example. Consider:

Function<Integer, Function<Integer,Integer>> makeAdder = x -> y -> x + y;

The above function is known as a makeAdder. What it does is take the integer x and create a new function. The new function then starts by taking an integer y, and when the initial is called, the new function adds x to y. This demonstrates higher order functioning because a new function is produced.

Higher order programming can be used in quite a number of applications in Java 8 functional programming.

Find out how to generate XML from XSD in Java right now!

3.Functions That Receive Other Functions and View Them as Arguments

Let’s say we had 2 functions defined as shown below;

Function<Integer,Integer> add1 = x -> x + 1;
Function<Integer,Integer> mul3 = x -> x * 3;

Now, if you went directly into this without really giving it second thoughts, you could just invoke these functions together by simply incrementing the integer and multiplying directly by 3 right? As shown below:

Integer x = 10;
Integer res = mul3.apply(add1.apply(x)); //yields 33

But what if we had a function to do all these two things at once?

For example, let’s have a look at the pseudo code below:

(f,g) -> x -> g( f(x) )

The above function, for example, takes two initially unary functions and proceeds to create a singular function that applies the 2 functions in an initial order. This method is known as function composition. Here is an interesting feature you didn’t know about functional compositions.

4. Functional Composition First Approach

We can utilize the binary operator method. This can be done by utilizing the sum operator:

BinaryOperator<Integer> sum = (a,b) -> a + b;
Integer res = sum.apply(1,2); // yields 3

But why not use the compose operator right away? Well, in this case, that seems a little complex because we will receive 2 binary functions instead of 2 integers.

BinaryOperator<Function<Integer,Integer>> compose = (f,g) -> x -> g.apply(f.apply(x));

We can now utilize this to create a compound function that sums 1 and then multiplies by 3, consecutively as shown:

Function<Integer,Integer> h = compose.apply(add1,mul3);
Integer res = h.apply(10); //yields 33

We have now combined the 2 functions.

5. Function Composition 2nd Approach

A simpler method is utilizing the compose method in java function library.

Function<Integer,Integer> h = mul3.compose(add1);
Integer res = h.apply(10);

You will receive a similar result as the methods initially used.

If you have further queries on Java functional programming, just get in touch with our high-level experts and we will gladly sort you out!