Java Interview Questions

30 Questions
Java

Java

Web DevelopmentBackend

Question 29

Explain the concept of functional interfaces.

Answer:

A functional interface in Java is an interface that contains exactly one abstract method. These interfaces are also known as Single Abstract Method (SAM) interfaces. Functional interfaces are designed to facilitate the use of lambda expressions and method references, which were introduced in Java 8. By having a single abstract method, they provide a clear target for lambda expressions, making the code more concise and readable.

Characteristics of Functional Interfaces

  1. Single Abstract Method: A functional interface has exactly one abstract method.
  2. Default and Static Methods: Functional interfaces can have any number of default and static methods, which do not affect the single abstract method requirement.
  3. @FunctionalInterface Annotation: While not mandatory, the @FunctionalInterface annotation can be used to explicitly declare a functional interface. This annotation is a form of documentation and helps the compiler enforce the contract by generating an error if the annotated interface does not meet the requirements of a functional interface.

Examples of Functional Interfaces

1. Predefined Functional Interfaces

The java.util.function package provides several predefined functional interfaces:

  • Predicate<T>: Represents a boolean-valued function of one argument.

    @FunctionalInterface
    public interface Predicate<T> {
        boolean test(T t);
    }
  • Consumer<T>: Represents an operation that accepts a single input argument and returns no result.

    @FunctionalInterface
    public interface Consumer<T> {
        void accept(T t);
    }
  • Function<T, R>: Represents a function that accepts one argument and produces a result.

    @FunctionalInterface
    public interface Function<T, R> {
        R apply(T t);
    }
  • Supplier<T>: Represents a supplier of results.

    @FunctionalInterface
    public interface Supplier<T> {
        T get();
    }

2. Custom Functional Interface

You can also define your own functional interfaces:

@FunctionalInterface
public interface MyFunctionalInterface {
    void execute();
    
    // You can add default and static methods
    default void defaultMethod() {
        System.out.println("This is a default method");
    }

    static void staticMethod() {
        System.out.println("This is a static method");
    }
}

Using Functional Interfaces with Lambda Expressions

Lambda expressions provide a concise way to implement the abstract method of a functional interface. Here are some examples:

Example 1: Using Predicate

import java.util.function.Predicate;

public class PredicateExample {
    public static void main(String[] args) {
        Predicate<String> isEmpty = s -> s.isEmpty();
        System.out.println(isEmpty.test(""));      // Output: true
        System.out.println(isEmpty.test("Hello")); // Output: false
    }
}

Example 2: Using Consumer

import java.util.function.Consumer;

public class ConsumerExample {
    public static void main(String[] args) {
        Consumer<String> print = s -> System.out.println(s);
        print.accept("Hello, World!"); // Output: Hello, World!
    }
}

Example 3: Using Function

import java.util.function.Function;

public class FunctionExample {
    public static void main(String[] args) {
        Function<Integer, String> intToString = i -> Integer.toString(i);
        System.out.println(intToString.apply(123)); // Output: 123
    }
}

Example 4: Using Supplier

import java.util.function.Supplier;

public class SupplierExample {
    public static void main(String[] args) {
        Supplier<String> stringSupplier = () -> "Hello, Supplier!";
        System.out.println(stringSupplier.get()); // Output: Hello, Supplier!
    }
}

Benefits of Functional Interfaces

  1. Conciseness: Lambda expressions provide a more concise way to implement functional interfaces compared to anonymous inner classes.
  2. Readability: Code becomes more readable and expressive when using lambda expressions and method references.
  3. Flexibility: Functional interfaces can be used in a variety of contexts, such as passing behavior as parameters or defining operations on collections.
  4. Interoperability with Streams: Functional interfaces are heavily used in the Stream API, making it easier to perform complex data processing operations.

Conclusion

Functional interfaces in Java are a key feature that supports lambda expressions and method references, enabling a functional programming style. They provide a way to pass behavior as parameters, making the code more flexible, concise, and readable. By leveraging predefined functional interfaces and creating custom ones, you can write more expressive and maintainable code in Java.

Recent job openings