Java 8 functional interface with example

We have already discussed, a lot of changes have been introduced in Java 8, like Default and static methods in interface, foreach method in Iterable Interface. Today we will discuss the java 8 functional interface and the annotation.

@FunctionalInterface

Functional interface

An interface with exactly one abstract method will be considered as a functional interface. The annotation @FunctionalInterface can be used to mark it as a functional interface. If an interface has only an abstract method then there is no need to even put the @FunctionalInterface annotation over it.

One of the major benefits of the functional interface is the possibility to use a lambda expression to instantiate them. We can instantiate them using an anonymous class but that code looks bulky.

Java 8 added a new Package java.util.function and the interfaces in this package are annotated with FunctionalInterface. Refer to the below description of the functional interface form Java doc.

Functional interfaces provide target types for lambda expressions and method references. Each functional interface has a single abstract method, called the functional method for that functional interface, to which the lambda expression’s parameter and return types are matched or adapted. Functional interfaces can provide a target type in multiple contexts, such as assignment context, method invocation, or cast context, like:

     // Assignment context
     Predicate<String> p = String::isEmpty;

     // Method invocation context
     stream.filter(e -> e.getSize() > 10)...

     // Cast context
     stream.map((ToIntFunction) e -> e.getSize())...

The Example of a functional interface is the Runnable interface. See the below implementation of the Runnable interface from Java source.

@FunctionalInterface
public interface Runnable {

    public abstract void run();

}

Let’s try to implement the Runnable interface with both anonymous class and with the lambda expression and see the difference.

Using Anonymous class

Thread t = new Thread(new Runnable() {
			
			@Override
			public void run() {
				System.out.println("The anonymous way");
			}
		});
		
		t.start();

Using Lambda expression

Runnable runnable = () ->{
		System.out.println("The lambda way");	
	};
	
	Thread t1 = new Thread(runnable);
	t1.start();

Let see some example of the valid functional interfaces:

(1) The best case will be interface with only one abstract method. Refer below example.

interface I1{
	
	int add(int a, int b);
}
public class MainTest {

	public static void main(String[] args) {

		I1 i = (a, b) -> {
			return a + b;
		};

		System.out.println(i.add(10, 20));
	}

}

// output will:- be the sum of a and b 30

(2) Interface with one abstract method and default method. Refer below example.

@FunctionalInterface
interface I2 {

	int add(int a, int b);
	
	default void display(){
		System.out.println("I am a functional interface");
	}
}

The interface I2 will be a valid functional interface even if you don’t put @FunctionalInterface annotation.

public class MainTest {

	public static void main(String[] args) {

		I2 i = (a, b) -> {
			return a + b;
		};
		int sum =  i.add(10, 20);
		System.out.println("the sum of a and b "+sum);
		
		i.display();
	}

}

/*
output will be:-
sum of a and b 30
I am a functional interface
*/

(3) Interface with one abstract method and with the default and static methods. Refer below example.

@FunctionalInterface
interface I3 {

	int add(int a, int b);
	
	default void display(){
		System.out.println("I am a functional interface");
	}
	
	static void foo(){
		System.out.println("I am a static method in a functional interface ");
	}
}

The interface I3 will be a valid functional interface even if you don’t put @FunctionalInterface annotation.

public class MainTest {

	public static void main(String[] args) {

		I3 i = (a, b) -> {
			return a + b;
		};
		int sum =  i.add(10, 20);
		System.out.println("sum of a and b "+sum);
		
		i.display();
		
		I3.foo();
	}

}

/* 
the output will be:-
the sum of a and b 30
I am a functional interface
I am a static method in a functional interface 
*/

Recommended Read

Java 8 Stream API with examples
Java 8 – Comparison with Lambda
Java 8 method reference with example

Happy Learning !!

Leave a Comment