{{announcement.body}}
{{announcement.title}}

Functional Interface Explained in Detail Introduced From Java 8

DZone 's Guide to

Functional Interface Explained in Detail Introduced From Java 8

In this article, explore functional interface introduced in Java 8.

· Java Zone ·
Free Resource

Functional interfaces are introduced as part of Java 8. It is implemented using the annotation called @FunctionalInterface. It ensures that the interface should have only one abstract method. The usage of the abstract keyword is optional as the method defined inside interface is by default abstract. It is important to note that a functional interface can have multiple default methods (it can be said concrete methods which are default) but only one abstract method. The default method has been introduced in interface so that a new method can be appended in the class without affecting the implementing class of the existing interfaces. Because prior to java 8 the implementing class of an interface has to implement all the abstract methods defined in the interface.

The functional interface has been introduced in Java 8 to support the lambda expression in java 8 on the other hand it can be said lambda expression is the instance of functional interface.

For example:

Java
 




x


 
1
@FunctionalInterface
2
 
          
3
Interface Area<T,S,R>
4
 
          
5
{
6
 
          
7
R calculateArea(T a, S b);
8
 
          
9
}


It is well known that how the above interface is implemented prior to java 8. But in java 8 it can be implemented in a smarter way. Find the below implementation.

Java
 




xxxxxxxxxx
1


 
1
static Area<Double, Double, Double> area = (a, b) ->(a*b);
2
 
          
3
System.out.println("The total area is "+ area.calculateArea(1.1,1.1));


The full implementation of the above functional interface details is available in GitHub, the link of which will be provided at the end of this tutorial.

In Java 8 there are 4 main functional interfaces are introduced which could be used in different scenarios. These are given below.

  1. Consumer
  2. Predicate
  3. Function
  4. Supplier

Among the above four interfaces, the first three interfaces also have extensions also which are given below.

Consumer - BiConsumer

Predicate – BiPredicate

Function – BiFunction, UnaryOperator, BinaryOperator

  1. CONSUMER

Let’s discuss about Consumer.

  • The consumer interface accepts one argument but there is no return value.
  • The name of function inside this interface is accept.
Java
 




xxxxxxxxxx
1
13


 
1
@FunctionalInterface
2
 
          
3
public interface Consumer<T> {
4
 
          
5
void accept(T t);
6
 
          
7
8
 
          
9
}
10
 
          
11
Consumer<String> ucConsumer = (s) -> System.out.println(s.toUpperCase());
12
 
          
13
ucConsumer.accept("consumer");


Output: CONSUMER

The above consumer is accepting one argument and print it in upper case. But there is no return value.

  • BICONSUMER

The extension of the Consumer which is BiConsumer accepts two arguments and return nothing.

Java
 




xxxxxxxxxx
1
19


 
1
@FunctionalInterface
2
 
          
3
public interface BiConsumer<T, U> {
4
 
          
5
void accept(T t, U u);
6
 
          
7
...
8
 
          
9
}
10
 
          
11
BiConsumer<String, String> biConsumer = (x,y) -> {
12
 
          
13
System.out.println(" x : " + x + " y : " + y );
14
 
          
15
};
16
 
          
17
biConsumer.accept("Sun" , "Moon");
18
 
          
19
Output: x: Sun y: Moon


  1. PREDICATE

Predicate will accept one argument, do some processing and then return boolean.

Java
 




xxxxxxxxxx
1
14


 
1
@FunctionalInterface
2
 
          
3
public interface Predicate<T> {
4
 
          
5
 
          
6
boolean test(T t);
7
 
          
8
...
9
 
          
10
}
11
 
          
12
static Predicate<Integer> p = (i) -> {return i%2 ==0;};
13
 
          
14
System.out.println("Result is p : " + p.test(4));


Output: true

  • BIPREDICATE

Instead of one argument BiPredicate will accept two arguments and return nothing.

  1. FUNCTION

This interface accepts one argument and return a value after the required processing. It is defined as below. The required processing logic will be executed on invocation of the apply method.

Java
 




xxxxxxxxxx
1


 
1
@FunctionalInterface
2
 
          
3
public interface Function<T, R> {
4
 
          
5
R apply(T t);
6
 
          
7
..
8
 
          
9
}


For example, the above Functional interface will be executed while the following code would be executed.

Java
 




xxxxxxxxxx
1


 
1
static Function<String,String> upperCase = (name) -> name.toUpperCase();
2
 
          
3
System.out.println("Result is : " + upperCase.apply("functional"));


Output: FUNCTIONAL

In the above example, the Function is accepting one string and also returns one string.

  • BIFUNCTION

The BiFunction is similar to Function except it accepts two inputs whereas Function accepts one argument. The sample code for the BiFunction interface is given below. In the below interface code T, U are the inputs and R is the single output.

Java
 




xxxxxxxxxx
1


 
1
@FunctionalInterface
2
 
          
3
public interface BiFunction<T, U, R> {
4
 
          
5
R apply(T t, U u);
6
 
          
7
……
8
 
          
9
}


  • UNARYOPERATOR and BINARYOPERATOR

Another two interfaces are UnaryOperator and BinaryOperator which extends the Function and BiFunction respectively. The following interface code snippets are given below for these two interfaces.

Java
 




xxxxxxxxxx
1
15


 
1
@FunctionalInterface
2
 
          
3
public interface UnaryOperator<T> extends Function<T, T> {
4
 
          
5
6
 
          
7
}
8
 
          
9
@FunctionalInterface
10
 
          
11
public interface BinaryOperator<T> extends BiFunction<T,T,T> {
12
 
          
13
...
14
 
          
15
}


From the above interfaces it is easy to understand that the UnaryOperator accepts a single argument and return a single argument but both the input and output argument should be of same of similar type.

On the other hand BinaryOperator accepts two arguments and return one argument similar to BiFunction but type of all the input and output argument should be of similar type.

The following examples for UnaryOperator and BinaryOperator interfaces are given respectively.

Java
 




xxxxxxxxxx
1


 
1
UnaryOperator<String> unaryOperator = (s)->s.concat("Operator");
2
 
          
3
System.out.println(unaryOperator.apply("Unary"));


Output: UnaryOperator

Java
 




xxxxxxxxxx
1


 
1
BinaryOperator<Integer> binaryOperator = (a,b) -> a+b;
2
 
          
3
System.out.println(binaryOperator.apply(3,4));


Output: 7

  1. SUPPLIER

Supplier functional interface does not accept any input rather return single output. The following interface code is given for understanding.

Java
 




xxxxxxxxxx
1
17


 
1
@FunctionalInterface
2
 
          
3
public interface Supplier<T> {
4
 
          
5
/**
6
 
          
7
* Gets a result.
8
 
          
9
*
10
 
          
11
* @return a result
12
 
          
13
*/
14
 
          
15
T get();
16
 
          
17
}



Find the below code example:-

Java
 




xxxxxxxxxx
1


 
1
public static Supplier<String> helloWorld = () -> {
2
 
          
3
return "Hello World";
4
 
          
5
};



Java
 




xxxxxxxxxx
1


 
1
String greeting = helloWorld.get();
2
 
          
3
System.out.println("The greeting message: "+greeting)



The above is just a simple example but it may be used in complex business scenario. For all the above scenarios download the sample code from here.

Topics:
functional interface, java, java 8, tutorial

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}