Exploring Java 8/3 : Functional Interface

Share on:

Hello there techie ninjas, I hope you are doing well.

Today in this blog we would be exploring Functional interfaces that were introduced in Java 8. Although we talked about functional interfaces a little bit, this blog would be completely hands-on on functional interfaces. We would be covering the Why, What, and How for the functional interfaces. If you haven't check out my previous blog "Lambda in java" please do checkout. That would set the stage for this blog. Let's get started then.

What is Functional Interface?

As we have seen in the previous blog, Functional Interface in Java 8 is an Interface in java with only a single abstract method. All Functional Interfaces are annotated with @FunctionalInterface annotation.

Why there is a need for a Functional Interface, or An Interface with only one abstract method?

With Java 8, Java is set the stage for supporting the functional programming style paradigm. Functional Programming says that you should treat the function as a first-class citizen, Object-oriented programming emphasis mutating the state of objects, while Functional programming says that you should never mutate the state of the object, instead your function should create immutable objects; and name of the function should clearly specify the final state of objects. For each such function, we can have a functional interface. Such a functional interface can be implemented very well using Lambda, and it would be easily readable and clean code. Although you would rarely need to create one since java 8 has a whole bunch of functional interfaces for n number of operations. You might see this information not so clear, but when you start programming in a functional style, you will come to know the advantage of it.

How to Declare your own functional interface?

It would be very easy, you can create a normal interface in java. To make your interface a functional interface, make sure it has only a single abstract un-implemented method. That all it required. Annotating your interface with @FunctionalInterface will tell the compiler that this interface would be used as a functional one, don't allow anyone in the future to add more methods. if so give compile error about that. However, it is optional, but a good safety net to work in a collaborative team.

Let's have look at below basic example of declaring a functional interface

1@FunctionalInterface
2interface MyInterface {
3    public void doSomething();
4}

Basic Functional Interfaces available in Java 8

Java 8 comes with a bunch of functional interfaces which are getting used in many of the Java 8 features like streams. There are some common functional interfaces that you will definitely face while doing functional programming. We would be exploring those. Once you are familiar with those, I am pretty sure that you will learn which one to use in which scenario. So let's get started with it.

Consumer Functional Interface

As the name tell this functional interface act as a consumer. Let's first understand what do you mean by a consumer. A consumer is something, which accepts input and processes it.
It won't give feedback to the caller. That means, it did not return anything. So while programming, if you come across such a scenario, you can use the consumer interface. A typical example would be printing something, write something to the database, send something to another client.

This is how the functional Interface look like for the Consumer

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

Below is an example of a consumer example that consumes string and prints it on the console.

 1import java.util.Arrays;
 2import java.util.List;
 3import java.util.function.Consumer;
 4
 5public class ConsumerExample {
 6    public static void main(String args[]) {
 7        List<String> listOfStrings = Arrays.asList("Apple", "Ball", "Cat", "Dog", "Egg", "Fish");
 8
 9        /* Easy way for beginners */
10        Consumer<String> printConsumer = (input) -> System.out.println(input);
11        listOfStrings.forEach(printConsumer);
12
13        /* Cleaner and shorter way */
14        listOfStrings.forEach((input) -> System.out.println(input));
15    }
16}

Predicate Functional Interface

As the name suggests, this interface has a method, named test. it will act as a predicate for the input. You can pass input to it. function body will have a code that can determine whether the pass input is valid for some condition, and it will return boolean. Let's have a look at the predicate functional interface available in java 8.

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

let's have a look at the below example, which demonstrates the usage of the predicate interface. In the below example, we have used the Streams API, which was introduced in java8. You might not be familiar with that, but as of now, you can think it is like an iterator on the lists. We would be going to learn about Streams API in-depth going ahead in this blog.

 1import java.util.Arrays;
 2import java.util.List;
 3import java.util.function.Predicate;
 4import java.util.stream.Collectors;
 5
 6public class PredicateExample {
 7    public static void main(String args[]) {
 8        List<String> listOfStrings = Arrays.asList("Apple", "Ball", "Cat",
 9            "Dog", "Egg", "Fish", "Ground",
10            "Horse", "Ice-Cream", "Juice",
11            "Kite", "Lemon", "Mango", "Nest",
12            "Orange", "Pears", "Queen", "Rat",
13            "Sun", "Tv", "Umbrella", "Volvo", "Watch", "Xray", "Zebra");
14
15        // Predicate which accept string, check its length and if it is 3 or less
16        // then return true otherwise it will return false
17        Predicate<String> predicate = (input) -> input.length() <= 3;
18
19        List<String> listWithOnly4letter = listOfStrings
20            // consider this as elements are iterating one by one
21            .stream()
22            // Applying our predicate, filter function which only
23            // send those value to next level for which predicate return true
24            .filter(predicate) 
25            // collect all element who pass ed filter test
26            .collect(Collectors.toList());
27
28        System.out.println(listWithOnly4letter);
29    }
30}

Supplier Functional Interface

As the name suggests, the Supplier functional interface deals only with supplying values without any input. this is how the supplier interface looks like.

1@FunctionalInterface
2public interface Supplier<T> {
3    T get();
4}

Let's have a look at the below example, where we have created a double supplier of random values. one can simply invoke the get method of it and they will get a random value.

1import java.util.function.Supplier;
2
3public class SupplierExample {
4    public static void main(String args[]) {
5        Supplier<Double> doubleSupplier = () -> Math.random();
6        System.out.println(doubleSupplier.get());
7    }
8}

Function Functional Interface

A function interface acts as a converter sort of thing. it accepts one parameter of type X and can return the value of type X or Y. whenever you have a use case of converting or transforming something into another form. you can use this interface. below is the signature of the functional interface

1@FunctionalInterface
2public interface Function<T, R> {
3    R apply(T t);
4}

Let's have a look at the below example, Again this example would be related to streams. think this example similar to the predicate example.

 1import java.util.Arrays;
 2import java.util.List;
 3import java.util.function.Function;
 4import java.util.stream.Collectors;
 5
 6public class FunctionalInterfaceExample {
 7public static void main(String args[]) {
 8
 9        List<String> listOfStrings = Arrays.asList("one", "two", "three");
10
11        Function<String, String> transformer = (str) -> str.toUpperCase();
12
13        String normalString = "abc";
14        String upperCaseString = transformer.apply(normalString);
15        System.out.println(upperCaseString);
16
17
18        List<String> upperCaseStringList = listOfStrings
19            .stream()
20            .map(transformer)
21            .collect(Collectors.toList());
22
23        System.out.println(upperCaseStringList);
24    }
25}

There are lots of other functional interfaces available in java 8. explore other functional Interfaces added as part of Java 8 in the package "java.util.function"

That's all for this tutorial friends. stay tune on Java4Ninja. See you in the next Blog.

<< Chapter 2 : Lambda In Java | Chapter 4 : Method & Constructor Reference in Java 8 >>

comments powered by Disqus