avatarFullStackTips

Summary

The provided web content discusses functional interfaces in Java 8, which are interfaces with exactly one abstract method, and their role in enabling functional programming concepts such as lambda expressions and method references.

Abstract

Functional interfaces in Java are a cornerstone of functional programming within the language, introduced in Java 8. These interfaces, characterized by having a single abstract method, serve as the foundation for lambda expressions and method references. The article explains the purpose of functional interfaces, which is to allow developers to treat functions as objects, facilitating their use as arguments, return values, or stored in variables. It highlights several common functional interfaces included in the Java Standard Library, such as Consumer, Supplier, Function, and Predicate, providing code examples to illustrate their usage. Additionally, the article encourages developers to create their own functional interfaces using the @FunctionalInterface annotation to enforce the single abstract method constraint and to clarify the intent of the interface. The article aims to provide a clear understanding of functional interfaces for those new to or needing a refresher on the concept, and it concludes by expressing anticipation for future engagement on related topics.

Opinions

  • The author assumes that readers familiar with Java 8 may already know about functional interfaces and might not need to read the entire article.
  • Lambda expressions are described as anonymous functions, suggesting they are a key feature of functional programming in Java.
  • The article implies that understanding functional interfaces is essential for leveraging the full capabilities of Java for functional programming.
  • It is suggested that the use of functional interfaces enhances code readability and maintainability by representing functions as objects.
  • The author emphasizes the practicality of functional interfaces by providing real-world code examples, indicating their frequent use in day-to-day development.
  • The article promotes the use of the @FunctionalInterface annotation as a best practice to indicate the intended use of the interface and to prevent the addition of extra abstract methods.

Functional Interfaces in Java?

functional interfaces in Java (image source:basicsstrong.com)

If you are already working on Java 8, then might know what is Functional Interface and may skip reading this blog. If not or if you want revise the basics of them, then continue reading it!

What is Functional Interface?

A functional interface in Java is an interface that specifies exactly one abstract method. You already know the abstract method is a method declaration without implementation.

Why we need it?

The functional interfaces are used as the basis for lambda expressions and method references in Java. If are not familiar with the lambda expressions and method references then it takes another post to explain in detail. So if you are not aware, to keep it short , you can think of lambda expression as anonymous function(a function without a name).

Let's continue…

Functional interfaces are needed because they provide a way for developers to represent functions as objects, which can be passed as arguments, returned from methods, or stored in variables. This makes functional interfaces a key component of functional programming in Java.

There are several functional interfaces available in the Java Standard Library, including

  1. java.util.function.Consumer<T> - Represents an operation that accepts a single input argument and returns no result.
  2. java.util.function.Supplier<T> - Represents a supplier of results.
  3. java.util.function.Function<T, R> - Represents a function that takes an argument of type T and returns a result of type R.
  4. java.util.function.Predicate<T> - Represents a predicate (a boolean-valued function of one argument).
  5. java.util.function.BinaryOperator<T> - Represents an operation upon two operands of the same type, producing a result of the same type as the operands.
  6. java.util.function.UnaryOperator<T> - Represents an operation on a single operand that produces a result of the same type as its operand.

Lets see the code example for first four interfaces in this list as they most used interfaces in our day to day development.

  1. java.util.function.Consumer<T>
Consumer<Integer> consumer = (x) -> System.out.println(x);
consumer.accept(10); // Output: 10

In this example, Consumer<Integer> is a functional interface that takes an integer as an input argument and doesn't return any result. The lambda expression (x) -> System.out.println(x) implements the accept method of the Consumer interface and takes an integer as input. When the accept method is called with the value 10, it outputs 10.

2. java.util.function.Supplier<T>

Supplier<String> supplier = () -> "Hello World!";
System.out.println(supplier.get()); // Output: Hello World!

In this example, Supplier<String> is a functional interface that doesn't take any input argument and returns a string. The lambda expression () -> "Hello World!" implements the get method of the Supplier interface and returns a string. When the get method is called, it returns the string "Hello World!".

3. java.util.function.Function<T, R>:

Function<Integer, String> function = (x) -> "Result: " + x;
System.out.println(function.apply(10)); // Output: Result: 10

In this example, Function<Integer, String> is a functional interface that takes an integer as input and returns a string. The lambda expression (x) -> "Result: " + x implements the apply method of the Function interface and takes an integer as input and returns a string. When the apply method is called with the value 10, it returns the string "Result: 10".

Can I create my own Functional Interface?

yes, you can also create your own functional interface by defining an interface with a single abstract method. For example

@FunctionalInterface
public interface MyFunctionalInterface {
    void doSomething(int x);
}

The @FunctionalInterface annotation is optional but it's a good practice to include it to indicate that the interface is intended to be a functional interface and to catch accidental attempts to add additional abstract methods.

Once you have defined your functional interface, you can implement it using a lambda expression or by providing an implementation class. For example

// Using a lambda expression
MyFunctionalInterface myFunction = (x) -> System.out.println("Input: " + x);
myFunction.doSomething(10); // Output: Input: 10

// Using an implementation class
class MyFunctionImpl implements MyFunctionalInterface {
    @Override
    public void doSomething(int x) {
        System.out.println("Input: " + x);
    }
}
MyFunctionalInterface myFunction2 = new MyFunctionImpl();
myFunction2.doSomething(20); // Output: Input: 20

In this example, we have defined a functional interface MyFunctionalInterface with a single abstract method doSomething that takes an integer argument x. We have implemented this interface using a lambda expression and an implementation class. When we call the doSomething method with the value 10 and 20 respectively, it outputs Input: 10 and Input: 20.

There are many more functional interfaces available in Java, these are just a few examples. These functional interfaces are part of the java.util.function package and provide a convenient way to write lambda expressions and method references in Java!

Hope you got some idea about the functional interfaces. Looking forward for your follow up for more blog posts!

Thanks for reading.

Java
Java8
Functional Interfaces
Java Functional Interface
Recommended from ReadMedium