Core Java

What is a Functional interface in Java 8? @Functional Annotation and Examples

The functional interface is one of the most important concepts of Java 8 which actually powers lambda expression but many developers don’t put enough effort to understand it and spend time learning lambda expression and Stream API without first understanding the role of functional interface in Java 8. Unless you know what is a functional interface and how lambda is related to it, you can’t use powerful features of Java 8 e.g. lambda expression and stream API. Without knowledge of functional interface, you won’t be able to understand where you can use a lambda in the code but also you will struggle to write lambda expression the method is expecting, hence, it’s important to have a good understanding of functional interface in Java 8.

In this article, I’ll try to fill that gap by explaining what is a functional interface, what is a @Functional annotation, how they are related to lambda expression and how they help you to use the lambda expression in your code.  So, let’s start with the very first thing, what is a functional interface?

What is Functional interface in Java 8

Well, a functional interface is nothing but an interface with just one abstract method e.g. Comparable, Runnable, EventListener, Comparator etc. You can see these interfaces were present in Java even before JDK 8, but why do we call such interface functional interface?

This is a very good question and if you know a little bit about functional programming, you know that it allows you to pass the code i.e. a function just like you pass data or object to the method.
These interface with just one abstract method was used to pass around code, just like you pass a function in functional programming language and that’s why they are called functional interface.

For example, you can directly pass the code to compare objects by creating an Anonymous class by implementing Comparator interface as shown below:

Collections.sort(list, new Comparator(){

public int compare(String s1, String s2){

return s1.length() - s2.length();

}

});

So, if you look closely, you can see we are passing code to a function using these interfaces. They are also known as strategy interface because this is an implementation of Strategy pattern where the code which forms the Strategy is injected into the code which runs that strategy at runtime.

Btw, if you don’t know what is Strategy pattern, then I suggest you go through From 0 to 1: Design Patterns – 24 That Matter – In Java, as knowledge of design pattern is important for effective coding in Java.

So, now that we know what is a functional interface, let’s understand how they are related to a lambda expression, and how an understanding of functional interface is important for writing code using a lambda expression?

Well, the most important thing to remember is that the only use of lambda expression in Java is to convert them into a functional interface.

This means you can pass lambda expression if a method is accepting a functional interface, which further means, you can pass a lambda to all existing method which accepts
Comparator, Runnable or any other interface which has got just one single abstract method.

This the reason that lambda expression in Java is also called of SAM type, where SAM means Single Abstract Method.

What does @Functional annotation do?

Now, let’s see what does @Functional annotation do? Will it make an interface functional if you just put the @Functional annotation on top of that? Well, no, it doesn’t do that. In fact, it’s
optional.

This means you can create a functional interface without using @Functioanl annotation just like you can override a method without putting the @Override annotation on top of a method. Then, what is the real purpose of @Functional annotation?

Well, it can ensure that the interface actually have just one abstract method and it also provides a hint to the tools like Javadoc that this interface is a functional interface. It’s pretty much similar to @Override annotation, which helps to prevent human error by verifying that you actually overriding a method.

Similar to @Override its best practice to put the @Functional annotation on top of the method with single abstract methods to indicate to the tools like Javadoc that they are a functional interface.

All the new functional interface added in java.util.function package is annotated with the @Functional annotation.

Btw, Yes, we have got more functional interfaces in JDK 8, particularly general-purpose functional interfaces like Predicate, Supplier, Consumer, Function, BiFunction, UnaryOperator etc. See
Java 8: basics for beginners to learn more about all those interfaces in depth.

These functional interfaces allow you to pass code to a function in form of lambda expression and enable the creation of powerful methods which can operate on those code e.g.
filter() which accept Predicate and allows you to pass a code which accepts one argument and return boolean.

How Functional interface and Lamda Expression are related

How does knowledge of functional interface affect the writing of lambda expression? Well, unless you don’t understand the functional interface, you can’t write a lambda expression which can be converted into that functional interface.

For example, the merge() method of java.util.Map interface accepts a BiFunction, but if you don’t know what is BiFunction then you cannot write lambda for that.

A BiFunction is a functional interface which has a method which accepts two arguments T and U and returns an object R.

This means you can pass a lambda to this method which works on two arguments and return an object e.g. merge(key, value, (v1, v2) -> v1 + v2) here (v1, V2) -> v1 + v2 is a lambda expression which can be converted into an instance of BiFunction functional interface.

A rather simpler example is Predicate which accepts a type T and returns a boolean. If you look filter() method of Stream class it accepts a Predicate:

filter(Predicate predicate)

This means you can pass any lambda expression which accepts one argument and return boolean to this method e.g. age -> age > 15 or s -> s.length == 15, both are acceptable, but if you don’t know what is a Predicate interface then you can’t do that.

Another example of a functional interface is Consumer which accepts an argument of type T and return nothing. A good use of this is made in the forEach() method of Iterable in JDK 8, as shown below:

forEach(Consumer action)

You can see that forEach() accepts a Consumer, which means you can pass it a lambda expression which has one argument and returns nothing or the void e.g.

s -> System.out.println(s)

The code System.out.println() return nothing, it just prints line in the console.

You can see that if you know functional interface then you can easily write a lambda expression to pass around, hence good knowledge of functional interface is mandatory. I suggest you go through all functional interface in java.util.function package and understand them.

I’ll explain about some of the more complex functional interfaces from the java.util.function package in coming articles but if you can’t wait then I suggest you go through this Java 9 Master Class course to learn more about lambdas and other Java 8 concepts.

That’s all about what is a functional interface in Java. You have also learned what is the role of @Functional annotation and why a good knowledge of functional interface is required to make effective use of lambda expression in your code in Java 8. If you are yet to start with Java 8, I suggest you do it now because in coming years everybody will code using Java 8 and if you don’t know lambda expression and new features introduced in Java 8 then you will be left behind.

Other Java 8 tutorials and Resources for further learning

What’s New in Java 8: Lambdas

How to sort HashMay by keys and values using lambdas?

How to use map and flatMap in Java 8?

How to do Map Reduce in Java 8?

How to convert lambda expression to method reference in Java 8?

Java SE 8 New Features – Full guide

Thanks for reading this article so far. If you like my explanation of Functional interface and @Functional annotation then please share with your friends and colleagues. If you have any questions or feedback then please drop a comment.

Published on Java Code Geeks with permission by Javin Paul, partner at our JCG program. See the original article here: What is a Functional interface in Java 8? @Functional Annotation and Examples

Opinions expressed by Java Code Geeks contributors are their own.

Javin Paul

I have been working in Java, FIX Tutorial and Tibco RV messaging technology from past 7 years. I am interested in writing and meeting people, reading and learning about new subjects.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button