Java 8 Functional Interfaces

Introduction:

Before jumping into learning functional interfaces, lets see what are they and why were they introduced.First of all ,there are 2 types of programming languages.Both styles are different programming paradigm’s:

  • Object oriented language(OOP)
  • Functional programming language

Java is the most popular OOP. For the reason that you are here reading about functional interfaces , I assume that you are very much familiar with object oriented stuffs.

Functional programming is a process of building software by composing pure functions,avoiding shared states.In simple words , functional programming consists of reusable blocks of code called functions, which is used at the one or more places in your code.

  • From java8 onward , oracle has added 2 new packages .
    • Java.util.function
    • java.util.stream

Java.util.function package has all the utilities to write functional programming stuffs.

What is a functional interface?

  • An interface which contains only one abstract function.
  • Represents abstract concepts such as functions,actions,predicates.
  • Read java docs for java.util.function for the list of all the functional interfaces.

Must know Functional interfaces:

  • Predicates – takes one argument and returns a Boolean
  • Consumer – takes a single argument and returns nothing.
  • Function – accepts one argument and produces a result.
  • Supplier – represents a supplier of results
  • Unary operator – single operator with return value
  • Binary operator – takes 2 arguments and returns one
InterfaceArgumentsReturnScenario
Predicate<T>TbooleanDoes the list contain value> 10
Consumer<T>TnothingConsume a list and print the values to a console
Function<T,R>TRFind out nth element inside the list.
Supplier<T>NoneTInitiate a list and return, a Factory method.
BinaryOperator<T>(T,T)TAdd 2 numbers and return the result
table 1.1

Code example:

Now lets look at a code example for a functional interface.The use case is to have have one interface for Greeting and 2 implementations to greet in different languages .In order to achieve this you need to declare the class ‘Greeting‘ as a functional interface @FunctionalInterface .

package com.ppkcodes.examples;

@FunctionalInterface
public interface Greeting {
    public abstract String greet(String name);
}

Since the use case is to greet in different languages,lets have 2 different implementations:

  • sayHello
  • sayNamaste

As a result,both implementations takes an string strName as input and appends either “Hello” or “Namaste” to it , and returns the string.

package com.ppkcodes.examples;

public class GreetingImpl {
    public static void main(String[] args) {
        Greeting sayHello=(strName) -> "Hello "+strName;
        Greeting sayNamaste=(strName)->"Namaste "+strName;

        System.out.println(sayHello.greet("Pramod"));
        System.out.println(sayNamaste.greet("Pramod"));
    }
}
Code output:
Hello Pramod
Namaste Pramod

Read this post for more code examples of functional interfaces. Few more functional interface examples specific to java8 can be found below:

You don’t always have to use @FunctionalInterface annotation to mark an interface as a functional interface.But , its a good practice to do so. Consequently,it will avoid adding additional methods accidentally. In case you add additional methods to such methods by mistake , the compiler will throw an error.

Why do we need Functional Interfaces?

If you look at the code example mentioned above, does it not seem obvious that it can be achieved without @FunctionalInterface ? If the answer is yes then why was it introduced in the first place?

First of all Functional interfaces was introduced mainly to instantiate Lambda expressions.

In functional programming ,code can be used as data.Using Lambda expressions, you can pass block of code as a reference to another method.They provide target types for Lambda expressions and method references.Ill explain more about it in a separate post.

Primitive variants of functional interfaces

The functional interfaces described in table 1.1 are generic in nature.E.g Predicate<T> means that the predicate takes an object of Type T. Here T can be an object or data structure like a List. Every java types can be a reference type T or a primitive type like int,double,byte,char.

Java8 supports functional interfaces for primitive types too. e.g: IntPredicate,LongConsumer,IntToLongFunction etc.

Because these specialized primitive variants avoid auto boxing operations involving primitives.

int i=2; // Primitive int
Integer j=3; //Autoboxing of int to Integer

In the above example , the variable j is costlier than variable i because j occupies memory in heap and i does not. As a result, there is a performance benefit of using primitive variables in your code.

Similarly , lets take another example of primitive vs generic functional interface.Can you guess which predicate is more efficient with respect to performance?

package com.codingbrains.examples;

import java.util.function.IntPredicate;
import java.util.function.Predicate;

public class SimplePredicate {

  public static void main(String[] args) {
    IntPredicate divisibleBy2= (i)->i%2==0; //Primitive int
    Predicate divisibleBy2Integer=(j)->(int)j%2==0; //Autoboxed Object Integer

    System.out.println("primitive int 5 is divisible by 2? "+divisibleBy2.test(5));
    System.out.println("Object Integer 5 is divisible by 2? "+divisibleBy2Integer.test(5));
  }
}

Certainly, the predicate divisibleBy2 is better because it uses a primitive integer and does not store the object in heap.

You may also like...

1 Response

  1. Akash says:

    Thank you for the explanation.

Leave a Reply

Your email address will not be published.