In Java, Functional Interface and Lambda Expressions are features introduced in Java 8 that
support functional programming.
✅ Functional Interface
A Functional Interface is an interface that has only one abstract method (but it can have
multiple default or static methods).
It can be used as the target for a lambda expression or method reference.
🔹 Example of a Functional Interface:
@FunctionalInterface
interface MyFunctionalInterface {
void sayHello(); // only one abstract method
}
✅ Lambda Expression
A Lambda Expression provides a clear and concise way to implement the abstract method of a
functional interface.
Syntax:
(parameters) -> { body }
🔹 Example using Lambda Expression:
public class LambdaDemo {
public static void main(String[] args) {
// Lambda expression to implement sayHello()
MyFunctionalInterface greet = () -> {
System.out.println("Hello from Lambda!");
};
// Call the method
greet.sayHello();
}
}
✅ Output:
Hello from Lambda!
🔍 Another Example: Functional Interface with Parameters
@FunctionalInterface
interface Calculator {
int operation(int a, int b);
}
public class LambdaCalculator {
public static void main(String[] args) {
// Lambda for addition
Calculator add = (a, b) -> a + b;
// Lambda for multiplication
Calculator multiply = (a, b) -> a * b;
System.out.println("Addition: " + add.operation(5, 3));
System.out.println("Multiplication: " + multiply.operation(5, 3));
}
}
✅ Output:
Addition: 8
Multiplication: 15
Java provides several built-in functional interfaces in the java.util.function package. Let's look at
two common ones:
✅ 1. Function<T, R>
Represents a function that takes one argument of type T and returns a result of type R.
🔹 Example:
import java.util.function.Function;
public class FunctionExample {
public static void main(String[] args) {
// Convert a string to its length
Function<String, Integer> stringLength = str -> str.length();
System.out.println("Length of 'Hello': " +
stringLength.apply("Hello"));
System.out.println("Length of 'Java': " + stringLength.apply("Java"));
}
}
✅ Output:
Length of 'Hello': 5
Length of 'Java': 4
Step-by-Step Explanation:
✅ import java.util.function.Function;
This line imports the Function interface from the java.util.function package.
Function<T, R> is a generic functional interface which takes:
o T: Input type
o R: Return type
It has one abstract method:
R apply(T t);
✅ public class FunctionExample { ... }
This is the definition of a public class named FunctionExample.
Java program execution starts from the main method of the class.
✅ Function<String, Integer> stringLength = str -> str.length();
This is the core of the program. Let's break it down:
Part Meaning
Function<String, You are creating a function that takes a String as input and returns an
Integer> Integer.
stringLength This is the name of the variable (a reference to the lambda function).
This is a lambda expression that implements the apply() method of the
str -> str.length() Function interface. It takes str as input and returns str.length() (the
number of characters in the string).
💡 This is the same as writing:
Function<String, Integer> stringLength = new Function<String, Integer>() {
public Integer apply(String str) {
return str.length();
}
};
But with a lambda expression, it’s shorter and more readable.
✅ stringLength.apply("Hello")
Calls the apply method of the Function interface.
Input: "Hello" → Output: 5 (because "Hello" has 5 characters)
✅ System.out.println(...)
Prints the result to the console:
Length of 'Hello': 5
Length of 'Java': 4
✅ Final Output:
Length of 'Hello': 5
Length of 'Java': 4
🎯 Summary
Function<T, R> is a built-in functional interface to transform data from one type to another.
Lambda expressions simplify implementing functional interfaces.
In this example, the string's length is calculated and printed using Function<String,
Integer>.
✅ 2. Predicate<T>
Represents a boolean-valued function of one argument (returns true or false).
🔹 Example:
import java.util.function.Predicate;
public class PredicateExample {
public static void main(String[] args) {
// Check if a number is even
Predicate<Integer> isEven = num -> num % 2 == 0;
System.out.println("Is 4 even? " + isEven.test(4));
System.out.println("Is 7 even? " + isEven.test(7));
}
}
✅ Output:
Is 4 even? true
Is 7 even? False
This Java program demonstrates the use of the Predicate functional interface from the
java.util.function package. Let's break it down:
🔹 What is a Predicate?
A Predicate<T> is a functional interface that represents a boolean-valued function of one
argument of type T.
It has a single method: boolean test(T t);
It is typically used for evaluating conditions.
🔹 Code Explanation
import java.util.function.Predicate;
This imports the Predicate interface.
public class PredicateExample {
public static void main(String[] args) {
A standard Java class with the main method (entry point).
// Check if a number is even
Predicate<Integer> isEven = num -> num % 2 == 0;
A Predicate<Integer> is defined using a lambda expression.
num -> num % 2 == 0 means: for a given number, return true if it is divisible by 2 (i.e.,
even), otherwise return false.
System.out.println("Is 4 even? " + isEven.test(4));
System.out.println("Is 7 even? " + isEven.test(7));
isEven.test(4) checks if 4 is even → prints true.
isEven.test(7) checks if 7 is even → prints false.
🔹 Output
Is 4 even? true
Is 7 even? false
NOTE:----These built-in interfaces save you from having to define your own interfaces for common
tasks.
quick summary of the most commonly used built-in functional interfaces in Java (from
java.util.function package):
✅ Core Functional Interfaces in Java 8+
Interface Parameters Returns Description
Function<T, R> T R Takes one argument and returns a result.
Predicate<T> T boolean Returns true or false for the given input.
Consumer<T> T void Performs an action (side-effect), no return.
Supplier<T> none T Supplies a result, no input parameter.
UnaryOperator<T> T T A Function where input and output are same type.
BinaryOperator<T> T, T T Takes two inputs of the same type and returns one.
🔹 Examples:
1. Consumer<T> – Print a string
import java.util.function.Consumer;
public class ConsumerExample {
public static void main(String[] args) {
Consumer<String> print = str -> System.out.println("Hello, " + str);
print.accept("World");
}
}
Output:
Hello, World
This Java program demonstrates the use of the Consumer<T> functional interface from the
java.util.function package. Let's break it down:
🔹 What is Consumer<T>?
Consumer<T> is a functional interface that takes a single input argument and returns
no result.
It's typically used to perform an action (like printing, logging, modifying) on an input.
It has a single method:
void accept(T t);
🔹 Code Breakdown
import java.util.function.Consumer;
Imports the Consumer interface.
public class ConsumerExample {
public static void main(String[] args) {
Standard Java class and the main() method (program entry point).
Consumer<String> print = str -> System.out.println("Hello, " + str);
This creates a Consumer<String> using a lambda expression.
The lambda str -> System.out.println("Hello, " + str) means:
o Take a String input called str
o Print "Hello, " followed by that string
print.accept("World");
Calls the accept() method with "World" as the argument.
The lambda gets executed, printing:
Hello, World
🔹 Output
Hello, World
2. Supplier<T> – Provide a value
import java.util.function.Supplier;
public class SupplierExample {
public static void main(String[] args) {
Supplier<Double> randomSupplier = () -> Math.random();
System.out.println("Random number: " + randomSupplier.get());
}
}
Output (example):
Random number: 0.837152682
This program demonstrates the use of the Supplier<T> functional interface from the
java.util.function package.
🔹 What is Supplier<T>?
Supplier<T> is a functional interface that supplies (provides) a result without taking
any input.
It’s commonly used for generating values like IDs, timestamps, random numbers, etc.
It has one method:
T get();
T: The type of value returned by the supplier.
🔹 Code Explanation
import java.util.function.Supplier;
Imports the Supplier interface.
public class SupplierExample {
public static void main(String[] args) {
Main class and method.
Supplier<Double> randomSupplier = () -> Math.random();
Creates a Supplier<Double> using a lambda expression.
() -> Math.random() is the implementation of get(), which returns a random double
between 0.0 and 1.0.
System.out.println("Random number: " + randomSupplier.get());
Calls the get() method to get the random value.
Prints the random number.
🔹 Output (Example)
Random number: 0.7312538249035913
(The actual number will vary each time you run the program.)
🔚 Summary
Interface Method Purpose
Supplier<T> get() Supplies a value, no input needed
✅ In this program:
Supplier<Double> supplies a random number using Math.random().
get() is called to retrieve and print that number.
3. UnaryOperator<T> – Square a number
import java.util.function.UnaryOperator;
public class UnaryOperatorExample {
public static void main(String[] args) {
UnaryOperator<Integer> square = x -> x * x;
System.out.println("Square of 5: " + square.apply(5));
}
}
Output:
Square of 5: 25
This program demonstrates how to use the UnaryOperator<T> functional interface in Java to
square a number.
🔹 What is UnaryOperator<T>?
UnaryOperator<T> is a specialized form of Function<T, R>, where:
o The input and output types are the same (T → T).
It represents an operation on a single operand that returns a result of the same type.
✅ Method:
T apply(T t);
🔹 Code Explanation
import java.util.function.UnaryOperator;
Imports the UnaryOperator interface from java.util.function.
public class UnaryOperatorExample {
public static void main(String[] args) {
Defines the main class and method.
UnaryOperator<Integer> square = x -> x * x;
A lambda expression that implements UnaryOperator<Integer>.
It takes an Integer x and returns x * x.
System.out.println("Square of 5: " + square.apply(5));
Calls the apply() method with input 5.
The lambda calculates 5 * 5 = 25 and prints:
Square of 5: 25
🔹 Output
Square of 5: 25
🔚 Summary
Interface Method Description
UnaryOperator<T> apply(T t) Takes one argument of type T, returns T
🔧 Use case:
You use UnaryOperator when the input and output types are the same, like:
o Squaring a number
o Negating a value
o Converting strings to lowercase
In this example, it squares the number 5 using apply(5).
4. BinaryOperator<T> – Multiply two numbers
import java.util.function.BinaryOperator;
public class BinaryOperatorExample {
public static void main(String[] args) {
BinaryOperator<Integer> multiply = (a, b) -> a * b;
System.out.println("5 * 3 = " + multiply.apply(5, 3));
}
}
Output:
5 * 3 = 15
This program demonstrates how to use the BinaryOperator<T> functional interface in Java to
multiply two numbers.
🔹 What is BinaryOperator<T>?
BinaryOperator<T> is a special form of BiFunction<T, T, T>, where:
o Both input arguments and the return type are of the same type.
It's used for operations on two operands of the same type, producing a result of the
same type.
✅ Method:
T apply(T t1, T t2);
🔹 Code Explanation
import java.util.function.BinaryOperator;
Imports the BinaryOperator interface.
public class BinaryOperatorExample {
public static void main(String[] args) {
Starts the main class and method.
BinaryOperator<Integer> multiply = (a, b) -> a * b;
A lambda expression implementing BinaryOperator<Integer>.
Takes two integers a and b, returns their product a * b.
System.out.println("5 * 3 = " + multiply.apply(5, 3));
Calls apply(5, 3), which evaluates 5 * 3 = 15.
Prints: 5 * 3 = 15
🔹 Output
5 * 3 = 15
🔚 Summary
Interface Method Description
BinaryOperator<T> apply(T t1, T t2) Takes two inputs of type T, returns a result of T
✅ Use cases:
Arithmetic operations: addition, multiplication, etc.
String concatenation
Combining values of the same type
In this example, it multiplies 5 and 3 using apply(5, 3).
4o