Functional Interfaces – Java 8

This is in continuation to the series of Lambda Expressions. In my previous post, I talked about Syntax of Lambda Expressions in Java 8. Let’s revise a little. We now know that a lambda expression is an anonymous function. It is not associated with any class. But Java is a strongly typed language and hence everything needs to have a type. So what’s the type of a lambda expression? A lambda expression can be used wherever the type is a Functional Interface, which has only one abstract method and lambda expression provides implementation of that method. And lastly, although there is the idea of type associated, there is no class and hence no object associated directly.

We’ve come across the term Functional Interface many times now. But what exactly is it? Any interface having just one method can be called a Functional Interface? No?

Well, starting from the basics. A Functional Interface is that interface which has one and only one ‘abstract’ method. Now all the Java folks would ask: but aren’t the methods defined in an interface already abstract? This was true till Java 7. In Java 8, we now have something called default methods. Default methods in an interface are those methods that provide an implementation within the interface itself. These methods are defined using the keyword, you guessed it right, default. Having default methods in an interface adds support for multiple inheritance of behavior in Java.

Now because we can have behavior in an interface, it makes sense to allow static methods to be added to interfaces as well. Static methods are defined in the same way they are defined elsewhere, using the static keyword. One important thing to note is the the static methods can only be called through the type reference and not through an instance variable. So if we have a class that has the same method as the interface that it implements, it’s not overriding the method.

Last thing about a functional interface is that in order to have the compiler check whether what we think is a functional interface really is, we can add an annotation to the functional interface @FunctionInterface and the compiler would then check if there’s only one abstract method in that particular interface and give an error if not.

Let’s have a look at some of those interfaces which were defined before Java 8 that can use lambda expressions to represent them.

public interface FileFilter { boolean accept(File x); }
public interface ActionListener { void actionPerformed(ActionEvent e); }
public interface Callable<T> { T call(); }
public interface Runnable { void run(); }

All these are interfaces were defined before Java 8, and now can be regarded as Functional Interfaces. Let’s have a look at another example:

1
2
3
4
5
6
7
public interface Predicate<T> {
    default Predicate<T> and(Predicate<? super T> p){ ... }
    default Predicate<T> negate(){ ... }
    default Predicate<T> or(Predicate<? super T> p){ ... }
    static <T> Predicate<T> isEqual(Object target){ ... }
    boolean test(T t);
}

Is the above interface a Functional Interface?

We have 5 different methods in the above interface. The methods on line 2, 3 and 4 are default methods and have an implementation. The isEqual() method on line 5 is a static method. So we are left with only one method test() which is neither default nor static and hence is an abstract method. The interface has one and only one abstract method, test() and hence Predicate is a Functional interface.

1
2
3
4
5
6
public interface Comparator<T>{
    //static and default methods elided
    int compare(T o1, T o2);
    boolean equals(Object obj);
}
 

Is this interface a Functional Interface? On the first look, it doesn’t seem like a Functional Interface. It has two abstract methods compare() and equals(). But that’s not the case. The equals() method is implicit from the Object class. Hence there’s just one abstract method in the interface and Comparator in fact is a Functional Interface. Aside from the topic, the equals() method was included in this interface and not in other interfaces just so to include in the javadoc above that particular method when it’s used in terms of compare.

Now when we want to use a lambda expression, we can either use it assigning to a variable or we can use it as a parameter to a function.

Callable c = () -> process();
new Thread(() -> process()).start();

In short, we can say that “A Lambda Expression provides an implementation of the single abstract method of the Functional Interface“.

That’s it for this one. Like, Follow, Share, Comment.

Share this:
Share
«
»

2 comments on “Functional Interfaces – Java 8”

  1. Jona says:

    Thank you for the auspicious writeup. It in fact was a amusement account it.
    Look advanced to far added agreeable from you! By the way, how
    could we communicate?

    1. Steve Mann says:

      I’m glad you liked the article. For communication, you can fill out the contact me page here. Or you can mail me directly at [email protected]

Leave a Reply