Java Built-in Functional Interfaces Interview Questions and Answers | Predicate, Function, Consumer, Supplier | Java 8
Master Java Built-in Functional Interfaces with real interview questions, Predicate, Function, Consumer, Supplier, BiFunction, UnaryOperator, BinaryOperator, Spring Boot examples, and production best practices.
Built-in Functional Interfaces Interview Questions and Answers
Introduction
Java 8 introduced several built-in Functional Interfaces in the java.util.function package to support Functional Programming and Lambda Expressions.
Before Java 8, developers often created custom interfaces for simple operations.
Example:
public interface EmployeeValidator {
boolean validate(Employee employee);
}
Java 8 eliminated the need for many custom interfaces by providing reusable Functional Interfaces such as:
- Predicate
- Function
- Consumer
- Supplier
- UnaryOperator
- BinaryOperator
- BiPredicate
- BiFunction
- BiConsumer
These interfaces are heavily used in:
- Spring Boot
- Stream API
- Spring Data JPA
- Kafka
- CompletableFuture
- Reactive Programming
- Collection APIs
Understanding them is essential for senior Java interviews.
Learning Objectives
After completing this article, you'll understand:
- Why built-in Functional Interfaces were introduced
- Predicate
- Function
- Consumer
- Supplier
- UnaryOperator
- BinaryOperator
- BiPredicate
- BiFunction
- BiConsumer
- Primitive Functional Interfaces
- Function chaining
- Production examples
- Interview questions
Functional Interface Hierarchy
flowchart TD
FunctionalInterfaces --> Predicate
FunctionalInterfaces --> Function
FunctionalInterfaces --> Consumer
FunctionalInterfaces --> Supplier
Function --> UnaryOperator
Function --> BinaryOperator
Predicate --> BiPredicate
Function --> BiFunction
Consumer --> BiConsumer
Most Common Functional Interfaces
| Interface | Input | Output | Purpose |
|---|---|---|---|
| Predicate | 1 | boolean | Validation |
| Function<T,R> | 1 | Result | Transformation |
| Consumer | 1 | Nothing | Process data |
| Supplier | None | Result | Generate data |
| UnaryOperator | 1 | Same Type | Modify object |
| BinaryOperator | 2 | Same Type | Combine objects |
Predicate
Represents a condition.
Method
boolean test(T t)
Example
Predicate<Employee> highSalary =
emp -> emp.getSalary() > 100000;
Usage
employees.stream()
.filter(highSalary)
.toList();
Function
Transforms one object into another.
Method
R apply(T value)
Example
Function<Employee,String> mapper =
Employee::getName;
Usage
employees.stream()
.map(mapper)
.toList();
Consumer
Consumes data without returning a value.
Method
void accept(T value)
Example
Consumer<Employee> printer =
System.out::println;
Usage
employees.forEach(printer);
Supplier
Produces data without taking input.
Method
T get()
Example
Supplier<UUID> generator =
UUID::randomUUID;
Usage
UUID id = generator.get();
UnaryOperator
A specialization of Function<T,T> where input and output types are the same.
UnaryOperator<String> upper =
String::toUpperCase;
BinaryOperator
A specialization of BiFunction<T,T,T> where both inputs and output are the same type.
BinaryOperator<Integer> max =
Integer::max;
Execution Flow
flowchart LR
Input --> FunctionalInterface["Functional Interface"]
FunctionalInterface["Functional Interface"] --> Lambda
Lambda --> BusinessLogic["Business Logic"]
BusinessLogic["Business Logic"] --> Result
Production Example
Predicate<Employee> active =
Employee::isActive;
Function<Employee,String> mapper =
Employee::getName;
Consumer<String> printer =
System.out::println;
employees.stream()
.filter(active)
.map(mapper)
.forEach(printer);
Spring Boot Example
List<EmployeeDTO> dtos =
repository.findAll()
.stream()
.filter(Employee::isActive)
.map(EmployeeDTO::new)
.toList();
This combines multiple built-in Functional Interfaces in a single Stream pipeline.
Frequently Asked Interview Questions
Question 1
What are built-in Functional Interfaces?
Answer
They are predefined Functional Interfaces available in the java.util.function package.
They eliminate the need to create custom interfaces for common operations such as validation, transformation, consumption, and object creation.
Question 2
Why did Java introduce built-in Functional Interfaces?
Answer
Before Java 8, developers repeatedly created custom interfaces for simple tasks.
Built-in Functional Interfaces:
- Reduce boilerplate code
- Improve code reuse
- Standardize APIs
- Integrate seamlessly with Lambda Expressions and Streams
Question 3
What is Predicate?
Answer
Predicate<T> represents a condition that returns a boolean.
Method:
boolean test(T value)
Example:
Predicate<Integer> even =
number -> number % 2 == 0;
Common use cases:
- Filtering
- Validation
- Authorization
- Business rules
Question 4
What is Function?
Answer
Function<T,R> transforms one object into another.
Method:
R apply(T value)
Example:
Function<Employee,String> mapper =
Employee::getName;
Common use cases:
- DTO conversion
- Entity mapping
- Data transformation
Question 5
What is Consumer?
Answer
Consumer<T> accepts input but returns no result.
Method:
void accept(T value)
Example:
Consumer<String> logger =
System.out::println;
Common use cases:
- Logging
- Sending notifications
- Writing files
- Processing records
Question 6
What is Supplier?
Answer
Supplier<T> produces an object without accepting input.
Method:
T get()
Example:
Supplier<LocalDateTime> now =
LocalDateTime::now;
Common use cases:
- Lazy initialization
- Random value generation
- UUID creation
- Default object creation
Question 7
What is the difference between Consumer and Supplier?
Answer
| Consumer | Supplier |
|---|---|
| Takes input | Takes no input |
| Returns nothing | Returns an object |
accept() |
get() |
Example:
Consumer<String> printer =
System.out::println;
Supplier<String> message =
() -> "Hello";
Question 8
What is UnaryOperator?
Answer
UnaryOperator<T> extends Function<T,T>.
Input and output types are the same.
Example:
UnaryOperator<String> upper =
String::toUpperCase;
Used when modifying an object without changing its type.
Question 9
What is BinaryOperator?
Answer
BinaryOperator<T> extends BiFunction<T,T,T>.
It accepts two values of the same type and returns one value of the same type.
Example:
BinaryOperator<Integer> max =
Integer::max;
Question 10
What is BiPredicate?
Answer
BiPredicate<T,U> accepts two parameters and returns a boolean.
Example:
BiPredicate<String,String> equals =
String::equals;
Common use cases:
- Comparing values
- Validation involving two inputs
Question 11
What is BiFunction?
Answer
BiFunction<T,U,R> accepts two parameters and returns a result.
Example:
BiFunction<String,String,String> join =
(a,b) -> a + b;
Question 12
What is BiConsumer?
Answer
BiConsumer<T,U> accepts two parameters and returns nothing.
Example:
BiConsumer<String,Integer> printer =
(name,age) ->
System.out.println(name + ":" + age);
Question 13
What are Primitive Functional Interfaces?
Answer
Primitive Functional Interfaces avoid boxing and unboxing overhead.
Examples:
IntPredicateLongPredicateDoublePredicateIntConsumerLongSupplierDoubleFunction
Using primitive variants improves performance when processing large amounts of primitive data.
Question 14
Can Functional Interfaces be chained?
Answer
Yes.
Examples:
Function chaining:
Function<String,String> trim =
String::trim;
Function<String,String> upper =
String::toUpperCase;
Function<String,String> combined =
trim.andThen(upper);
Predicate chaining:
Predicate<Employee> active =
Employee::isActive;
Predicate<Employee> highSalary =
emp -> emp.getSalary() > 100000;
Predicate<Employee> eligible =
active.and(highSalary);
Question 15
Where are built-in Functional Interfaces used in Spring Boot?
Answer
Common use cases include:
- Stream processing
- DTO mapping
- Repository filtering
- Event listeners
- Retry callbacks
- Asynchronous processing
- Security authorization
- Validation logic
- Kafka consumers
- CompletableFuture pipelines
Question 16
Should we create custom Functional Interfaces?
Answer
Only when the built-in interfaces cannot clearly express the business requirement.
Prefer:
PredicateFunctionConsumerSupplier
before creating custom interfaces.
Question 17
Which Functional Interface is used by Stream.filter()?
Answer
Predicate<T>
Example:
employees.stream()
.filter(Employee::isActive);
Question 18
Which Functional Interface is used by Stream.map()?
Answer
Function<T,R>
Example:
employees.stream()
.map(Employee::getName);
Question 19
Which Functional Interface is used by forEach()?
Answer
Consumer<T>
Example:
employees.forEach(System.out::println);
Question 20
Which Functional Interface is most commonly used in production?
Answer
The most commonly used are:
- Predicate
- Function
- Consumer
- Supplier
These four cover the majority of functional programming requirements in enterprise applications.
Real-Time Interview Scenario
Question
A Spring Boot application loads all employees, filters active records, converts them into DTOs, and logs each DTO.
Which Functional Interfaces are involved?
Answer
Predicate<Employee>→ Filter active employeesFunction<Employee, EmployeeDTO>→ Convert entity to DTOConsumer<EmployeeDTO>→ Log or process each DTO
Best Practices
- Prefer built-in Functional Interfaces over custom ones.
- Use method references whenever they improve readability.
- Use primitive Functional Interfaces for performance-critical code.
- Keep Lambda expressions short and focused.
- Chain
PredicateandFunctionoperations instead of writing nested logic. - Use meaningful variable names for Functional Interfaces.
Common Mistakes
❌ Creating unnecessary custom Functional Interfaces.
❌ Confusing Consumer with Function.
❌ Using Supplier when input parameters are required.
❌ Ignoring primitive Functional Interfaces in performance-sensitive applications.
❌ Writing long and complex Lambda expressions.
Interview Tips
Senior interviewers commonly ask:
- Explain the differences between
Predicate,Function,Consumer, andSupplier. - Why is
UnaryOperatora specialization ofFunction? - When should you use
BinaryOperatorinstead ofBiFunction? - What are primitive Functional Interfaces, and why do they matter?
- Which Functional Interfaces are used internally by the Stream API?
- How are these interfaces used in Spring Boot?
Being able to identify the correct Functional Interface for a given problem is a strong indicator of Java expertise.
Summary
In this article, we covered:
- Built-in Functional Interfaces
- Predicate
- Function
- Consumer
- Supplier
- UnaryOperator
- BinaryOperator
- BiPredicate
- BiFunction
- BiConsumer
- Primitive Functional Interfaces
- Function chaining
- Spring Boot production examples
- Frequently asked interview questions
- Best practices
- Common mistakes
In the next article, we'll explore Functional Programming Best Practices, including immutability, avoiding side effects, debugging Lambdas, performance tuning, parallel streams, code review guidelines, and production-ready design principles.