Select Page

Working with Functional Interfaces in Java

Joydip Kanjilal
Published: August 23, 2022

Java Developer Tutorials

An interface is a contract that defines a set of methods and their signatures. Any class can extend this interface and implement the methods of this interface. The Java Programming Language has provided support for interfaces since the earliest versions of the language.

Functional interfaces are a popular feature of Java that was added to the language in version 8. They allow developers to create functions as first-class objects, which opens up new possibilities for creating reusable code and simplifying development processes.

This Java programming tutorial will look at functional interfaces, how they work, why they are helpful, and some examples of how developers might use them in their projects.

Interested in learning how to program in Java in a classroom or course environment? We have a list of the Top Online Courses to Learn Java that can help get you started.

What are Functional Interfaces in Java?

A functional interface in Java is an interface that consists of just one abstract method (i.e., a method that is not implemented). Although this method must have a return type, it cannot accept arguments. The method must also be public and in an accessible class or interface.

Besides one abstract method, you can create the following methods in a functional interface in Java:

  • Default methods
  • Static methods
  • Methods inherited from the Object class

Here is a simple code example of a functional interface in Java:

public interface MyFunctionalInterface 
  void doSomething(); 

As you can see, this interface only has a single abstract method.

How to Program the Comparer Interface in Java

One common example of a functional interface is the Comparator interface, which is used to compare two objects. It has the following abstract method:

int compare(T obj1, T obj2); 
Here's how the Comparer interface is defined in Java: 
public interface Comparator {
	int compare(T o1, T o2);
	boolean equals(Object obj);
	//Other methods...

The Comparator interface can be used to sort a list of objects by their natural order or by a custom order that you define. For example, a programmer could use the Comparator interface to sort a list of strings by their length:

List listStrings = Arrays.asList("ABC", "XYZ", "PQR"); 
listStrings.sort((s1, s2) -> s1.length() - s2.length());

You can also reverse the order of the list:

listStrings.sort((s1, s2) -> s2.length() - s1.length());

The @FunctionalInterface Annotation in Java

In Java 8, the annotation @FunctionalInterface marks an interface as a functional interface. You can mark an interface with this annotation to generate compiler errors if your interface contains more than one abstract method. A functional interface in Java is often used in lambda expressions and it can have several default methods.

It should be noted that the annotation @FunctionalInterface is optional. If an interface contains one abstract method but no @FunctionalInterface annotation, it is still a functional interface and may be the target type of lambda expressions. The annotation prevents us from mistakenly modifying a functional interface into a non-functional interface since the compiler will flag an error.

Read: The Best Tools for Remote Developers

What are the Benefits of Functional Interfaces in Java?

The most significant benefit of Functional interfaces is that they make it possible to create abstractions that multiple classes can use without copying and pasting code. This is especially helpful when developers need to create a complex abstraction with various methods and behaviors.

In Java, using Functional interfaces, programmers can pass a function as a parameter instead of a reference object, which reduces the amount of boilerplate code you have to write.

In functional programming, a piece of code may be considered data. This is where lambda expressions help. You can use lambda expressions to pass code to another function or object.

It should be noted that lambda expressions use a Functional interface as a data type. Because there is just one abstract method in a functional interface, the implementation of that method becomes the code that can be passed as an argument to another method.

Using Anonymous Inner Classes to implement Functional Interfaces

As shown in the code example below, programmers used anonymous inner classes or objects to implement such interfaces before Java 8:

class Test {
    public static void main(String args[])
        new Thread(new Runnable() {
            @Override public void run()
                System.out.println("Hello World!");

Built-in Functional Interfaces in Java

In addition to the Comparator and Runnable interfaces, there are many other built-in functional interfaces in Java 8, such as Callable, Predicate, Function, and Consumer. These interfaces can be found in the java.util.function package.

Here is a brief discussion on the most commonly used built-in interfaces in Java:

  • Comparator: A Comparator is an interface used to compare two objects based on certain criteria. The java.util.Comparator class is used to implement this interface.
  • Runnable: It is an abstract class that implements the Runnable interface and provides an abstraction for running a thread.
  • Callable: It represents a task that returns a single result value T, which can be accessed by calling its call() method.
  • Future: A Future represents an asynchronous operation whose result may not yet be available but will eventually become available at some point in time in future when all pending activities have been completed successfully or unsuccessfully.
  • Supplier: A Supplier is simply a function that returns values without taking input parameters; these are also known as pure functions.
  • Predicate: The Predicate functional interface represents predicates which return true or false for some condition specified by their boolean parameter type T.
  • Consumer: The Consumer functional interface represents functions that accept parameters of type T and returns no results.

How to Implement a Custom Functional Interface in Java

Functional interfaces can be created in two ways: an existing interface can be converted into a Functional interface by adding the @FunctionalInterface annotation. Alternatively, programmers can have an interface containing just one abstract method. The following code example is a complete example that illustrates how you can define and use a Functional interface in Java:

    interface Test{  
        void display(String message);  
    public class TestImplementation implements Test{  
        public void display(String message){  
        public static void main(String[] args) {  
            TestImplementation obj = new TestImplementation();  
            obj.display("Hello World!");  

Final Thoughts on Functional Interfaces in Java

The introduction of lambda expressions in Java 8 provided a new syntactic improvement over its earlier counterparts and helped eliminate boilerplate code in your applications. Functional interfaces are a first-class citizen of Java and their implementation can be treated as lambda expressions. Functional interfaces make it easier to write functional-style code by reducing the verbosity of anonymous inner classes.

Functional interfaces are a great way to add some flexibility to your code. By using a Functional interface, coders can specify exactly what functionality you need from an object, and then have that object be implemented by any class that meets your requirements.

Read more Java programming tutorials and software development guides.