Functional Interface

Interface in java contains abstract methods. Up to Java 7, An Interface contained only one abstract method called Single Abstract Method Interface or SAM. Those interfaces contain a single functionality.

After java 8, the Single Abstract Method or SAM are also known as Functional Interfaces. The Functional Interfaces instances can be used to represent lambda expressions or method references. The Functional Interfaces can have any number of default methods and static methods.

The functional Interface helps to achieve functional programming approach

java.lang.Runnable, java.awt.event.ActionListener, java.util.Comparator and java.util.concurrent.Callable are some Functional interfaces.

package org.wesome.java8;

interface Apple {
    void show();
}

The syntex for Java 8 lambda is

FunctionalInterface instanceVariable = (input parameters) -> {}

The above program will be converted to Java 8 lambda as below.

package org.wesome.java8;

interface Apple {
    void show();
}

class Fuji {
    public static void main(String[] args) {
        Apple apple = () -> {
            System.out.println("i love Apple");
        };
        /*  since it's a single line method hence input type return and brackets are not required   */
        Apple apple1 = () -> System.out.println("i love Apple");

        apple.show();
        apple1.show();
    }
}

What is a Functional Interface

A Functional Interface should have a single abstract method but can contain multiple static and default methods. if multiple abstract methods are provided, the compiler will throw an error at execution time.

package org.wesome.java8;

interface Apple {
    void show();

    void eat();

    static void price() {
        System.out.println("Fuji Apple is very costly.");
    }

    default void taste() {
        System.out.println("Fuji Apple is very sweet.");
    }
}

To enforce the Single Abstract method, Java 8 provides an optional @FunctionalInterface annotation to mark the Single Abstract Method Interface or Functional Interfaces. It will make sure the Interface should not have more than 1 abstract method or else it will throw a compilation error.

@FunctionalInterface annotation is optional but recommended to use

package org.wesome.java8;

@FunctionalInterface
public interface Apple {
    void show();

    static void price() {
        System.out.println("Fuji Apple is very costly.");
    }

    default void taste() {
        System.out.println("Fuji Apple is very sweet.");
    }
}

A normal Interface can have an abstract method, but an Interface with @FunctionalInterface annotation must have an abstract method.

@FunctionalInterface
interface Apple extends Tree {
}

A Functional Interface can extend other normal Interfaces which may have default and static methods but should not have an abstract method.

interface Tree {
    static void fruit() {
        System.out.println("i am tree, i give fruits.");
    }

    default void wood() {
        System.out.println("i am tree, i give woods.");
    }
}

@FunctionalInterface
interface Apple extends Tree {
    void show();
}

A Functional Interface cannot extend another Functional Interface.

@FunctionalInterface
interface Tree {
    void fruit();
}

@FunctionalInterface
interface Apple extends Tree {
    void show();
}

Java built-in Function Interface

Java 8 allows developers to create Functional Interfaces for Lambda Expression, Java also provides java.util.function package which has different types of pre-built-in Functional Interfaces for most of the general purpose use cases.

  • Consumer

The Java Consumer interface defined in java.util.function.Consumer. It takes the input parameter but doesn't return any value.

@FunctionalInterface
public interface Consumer<T> {
    void accept(T t);
}

an example of a Consumer would be.

package org.wesome.java8;

import java.util.function.Consumer;

@FunctionalInterface
interface Tree<T> {
    void show(T apple);
}

class Apple {
    public static void main(String[] args) {
        Tree<String> consumer = apple -> System.out.println(apple);
        consumer.show("i love apple");
    }
}
  • Predicate

The Java Predicate interface defined in java.util.function.Predicate. It takes a single value as a parameter and returns a boolean (true or false) value.

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

an example of predicate would be

package org.wesome.java8;

import java.util.function.Consumer;

@FunctionalInterface
interface Tree<T> {
    boolean checkForEmpty(T apple);
}

class Apple {
    public static void main(String[] args) {
        Tree<String> predicate = apple -> apple.isEmpty();
        System.out.println(predicate.checkForEmpty("i love apple"));
    }
}
  • Function

The Java Function interface defined in java.util.function.Function. It takes a single parameter and returns a single value.

@FunctionalInterface
public interface Function<T,R> {
    public <R> apply(T parameter);
}

an example of function

package org.wesome.java8;

import java.util.function.Consumer;

@FunctionalInterface
interface Tree<T, R> {
    R countCharacters(T apple);
}

class Apple {
    public static void main(String[] args) {
        Tree<String, Integer> function = apple -> apple.length();
        System.out.println(function.countCharacters("apple"));
    }
}
  • Supplier

The Java Supplier interface is defined in java.util.function.Supplier. is a functional interface that supplies a value as a factory interface. it returns output without taking any input.

@FunctionalInterface
public interface Supplier<T> {
    T get();
}

an example of a supplier

package org.wesome.java8;

import java.time.LocalDate;
import java.util.function.Consumer;

@FunctionalInterface
interface Tree<T> {
    T today();
}

class Apple {
    public static void main(String[] args) {
        Tree<LocalDate> supplier = () -> LocalDate.now();
        System.out.println("i ate apple on " + supplier.today());
    }
}

Supplier is majorly used as default value of findFirst or findAny function.

package org.wesome.java8;

import java.util.Arrays;
import java.util.List;
import java.util.function.Supplier;

class Apple {
    public static void main(String[] args) {
        Supplier<String> supplier = () -> "Fuji";

        List<String> list = Arrays.asList("Jonagold", "Gala", "Macintosh");

        String apple = list.stream().filter(app -> app.startsWith("F")).findFirst().orElseGet(supplier);
        System.out.println("apple starts with F is " + apple);
    }
}

 

The above first 3 functional interfaces have extensions or subinterfaces.

  • Consumer -> Bi-Consumer
  • Predicate -> Bi-Predicate
  • Function -> Bi-Function, Unary Operator, Binary Operator

follow us on