Tuesday, November 5, 2019

Java 8: Functional Interfaces

Any interface with a SAM(Single Abstract Method) is a functional interface, and its implementation may be treated as lambda expressions.

Read below for detailed explanation

Java is an Object Oriented Programming.

When we say that, what does it means ? it wants to imply that without object you can't do anything. You require an object or mother of object i.e. class to call a function, access any field etc.

sometimes this creates lots of noise. let's suppose you just wanted to add two numbers, means you require a function which accepts 2 numbers, which adds them and returns the result.

in Java to expose this functionality, you have to write a Utility class and then write a method which accepts arguments and sum it up.

public class mathUtil {

         public static T add( T a, T b) {
                return a+b;
         }
}

now, wherever you wanted to use it, you have to call like MathUtil.add(4,5);

is it worth writing whole class for using it ? can't we directly use function to add it without the class, as class is just adding noise.

till Java 7 it is not allowed however from Java 8 it is allowed via a hook named lambda expressions, where you can perform some function without formally creating any class of it.

so above code can be written like this and used wherever we can pass lambda expression.
                  (a,b) -> a +b;

Basically Java 8 provided support for lambda expression using interfaces called Functional interfaces.

What the hack is Functional interface now ?

The Functional interface is any interface which exactly has one abstract method.

i.e. our old friend Runnable, Comparator interfaces are Functional interface as they hold only one method. To make sure any interface is really functional we can annotate them with @FunctionalInterface, by which compiler will ensure that interface contains only one abstract method.


@FunctionalInterface
public interface myInterface{
      public void doThis(T a);
}

As you are aware any interface can contain default() and static() methods from java 8, so same applies to Functional Interface.

When we talk about function, a function can do any of the below:

1. Consume something and return nothing (Consumer).
2. Accept nothing and just return something (Supplier)
3. Accept something and judge it (Predicate)
4. Accept something and return something (Function)

As these are the common activities for any function, Java  8 java.util.function package provides functional interfaces for all of these as well various variants of these, full list here.

Most of the time your function will fall under one of the category you just have to use them, no need to write functional interfaces.

Here are the basic definitions of each:

public interface Function<T,R> {

    public <R> apply(T parameter);
}
public interface Predicate {
    boolean test(T t);
}
public interface Consumer<T>{
    void accept(T t)
} 
public interface Supplier<T>{
    T get()
} 

Few Examples:

package madwani.sushil;
import java.util.function.Consumer;import java.util.function.Function;import java.util.function.Predicate;import java.util.function.Supplier;
public class FunctionalInterfaceExample {

    public static void main(String[] args) {

        Predicate isNotNull = (value) -> value!=null;
        System.out.println(isNotNull.test("hello"));

        Supplier<Double> randomGenerator = () -> Math.random();
        System.out.println(randomGenerator.get());

        Function<String, Integer> integerConv = Integer::parseInt;
        System.out.println(integerConv.apply("2"));

        Consumer<Integer> exitCode = (num) -> System.exit(num);
        exitCode.accept(20);    }
}





No comments: