What is Functional Programming?
Functional Programming (FP) is a programming style where you write programs by building functions that perform computations. Instead of focusing on how to solve a problem (step-by-step instructions), you focus on what result you want.
Definition: Functional Programming is a way of coding where you avoid changing state and use pure functions to describe what should happen.
🔹 Key Concepts of Functional Programming
Description | Java Example | |
Functions as first-class citizens | Functions can be assigned to variables, passed as arguments, or returned from other functions | Function<String, Integer> f = s -> s.length(); |
Pure Functions | Given the same input, always return the same output. No side effects | x -> x * 2 |
Immutability | Data is not changed. New copies are created with updated values | List<String> result = list.stream().filter(...) |
Declarative Style | Focus on what to do, not how to do it | list.stream().filter(x -> x > 5) |
Higher-Order Functions | Functions that accept or return other functions | map(), filter() in Streams |
Lazy Evaluation | Execution is deferred until needed | Stream.generate(() -> Math.random()) |
Recursion | Replacing traditional loops with recursive function calls | Used in functional-style programming |
🔹 Brief History of Functional Programming
- 1950s – Introduced with LISP, one of the first FP languages.
- 1970s–90s – Languages like Haskell and Scala promoted pure FP.
- 2000s–present – Mainstream languages (Java, JavaScript, Python) adopted FP features.
🔹 Functional Programming in Java (Since Java 8)
Java began supporting Functional Programming with Java 8, bringing:- Lambda Expressions – Anonymous functions for cleaner, inline code.
- Functional Interfaces – Interfaces with a single abstract method (e.g., Predicate, Function).
- Streams API – Declarative data processing pipelines.
🔹 Example: Funcational Programming
//Filter even numbers using streams
What is Lambda Expression?
A Lambda Expression is a concise way to represent an anonymous function (a block of code with inputs and outputs but no name).
🔹 Syntax of Lambda Expression
-
Curly braces
{}
can be omitted for single-line expressions. -
Type declarations are usually inferred.
Without Lambda (Old Way):
With Lambda (Modern Way):
🔹 Advantages of Lambda Expressions
Benefit | Description |
Less Code | No need for anonymous inner classes |
More Readable | Focuses on logic instead of boilerplate |
Enables FP | Works seamlessly with Streams, Collections, etc. |
Enables Concurrency | Fits well with parallel operations and callback structures |
What is Method Reference?
Method Reference is a shorthand for lambda expressions that just call an existing method.
It's more concise, readable, and avoids boilerplate.
Lambda vs Method Reference — At a Glance
Lambda Expression
Equivalent Method Reference
x -> System.out.println(x)
System.out::println
(a, b) -> Math.max(a, b)
Math::max
str -> str.toUpperCase()
String::toUpperCase
() -> new ArrayList<>()
ArrayList::new
Types of Method References
Type
Syntax
Example
Static method
Class::staticMethod
Math::abs
Instance method of object
obj::instanceMethod
System.out::println
Instance method of class type
Class::instanceMethod
String::toLowerCase
Constructor
Class::new
ArrayList::new
Method Reference is a shorthand for lambda expressions that just call an existing method.
It's more concise, readable, and avoids boilerplate.
Lambda vs Method Reference — At a Glance
Lambda Expression | Equivalent Method Reference |
x -> System.out.println(x) | System.out::println |
(a, b) -> Math.max(a, b) | Math::max |
str -> str.toUpperCase() | String::toUpperCase |
() -> new ArrayList<>() | ArrayList::new |
Types of Method References
Type | Syntax | Example |
Static method | Class::staticMethod | Math::abs |
Instance method of object | obj::instanceMethod | System.out::println |
Instance method of class type | Class::instanceMethod | String::toLowerCase |
Constructor | Class::new | ArrayList::new |
Example: Lambda vs Method Reference
import java.util.*;
import java.util.function.*;
public class MethodReferenceComparison {
public static void main(String[] args) {
List<String> names = Arrays.asList("Java", "Python", "Go");
// Lambda: prints each name
names.forEach(name -> System.out.println(name));
// Method Reference (same as above)
names.forEach(System.out::println);
// Lambda: convert to upper case
List<String> upper = names.stream()
.map(name -> name.toUpperCase())
.toList();
// Method Reference
List<String> upper2 = names.stream()
.map(String::toUpperCase)
.toList();
// Static method reference (Math.max)
BiFunction<Integer, Integer, Integer> lambdaMax = (a, b) -> Math.max(a, b);
BiFunction<Integer, Integer, Integer> refMax = Math::max;
System.out.println("Lambda Max: " + lambdaMax.apply(10, 20));
System.out.println("Ref Max: " + refMax.apply(10, 20));
// Constructor reference
Supplier<ArrayList<String>> lambdaList = () -> new ArrayList<>();
Supplier<ArrayList<String>> refList = ArrayList::new;
System.out.println("List created using constructor ref: " + refList.get());
}
}
Output
Java
Python
Go
Lambda Max: 20
Ref Max: 20
List created using constructor ref: []
Summary Method Reference
- Use Lambda when logic is custom or short-lived.
- Use Method Reference when reusing existing methods.
- Both are interchangeable in many cases but method references are cleaner when applicable.
What is a Functional Interface?
A Functional Interface is an interface with exactly one abstract method, which makes it suitable for lambda expressions or method references.
🔹 Example: Custom Functional Interface
Note: The
@FunctionalInterface
annotation is optional but recommended. It ensures the interface contains only one abstract method.
🔹 Built-in Functional Interfaces in Java
Java provides many pre-defined functional interfaces in the java.util.function
package:
Interface | Input | Output | Example |
Predicate<T> | T | boolean | x -> x > 10 |
Function<T, R> | T | R | x -> x + 1 |
Consumer<T> | T | void | x -> System.out.println(x) |
Supplier<T> | none | T | () -> "Hello" |
BinaryOperator<T> | T, T | T | (a, b) -> a * b |
🔹 Example: Built-in Functional Interfaces
🔹 Final Summary
Topic | Summary |
Functional Programming | Focuses on what to solve using pure functions and immutable data |
Lambda Expressions | Anonymous, concise functions ((a, b) -> a + b) |
Functional Interface | Interface with one method; enables lambda usage |
Streams API | Declarative data processing using map(), filter(), collect() |
Benefits | Modular, thread-safe, testable, readable, and expressive code |
Advanced Concepts | Higher-order functions, recursion, lazy evaluation, function composition |