📘LESSON 3
3.1 Lesson Outcomes
After completing this lesson, learners will be able to:
- Explain functional programming concepts in Java.
- Differentiate between functional and structural programming.
- Use lambda expressions and streams.
- Apply intermediate and terminal stream operations.
- Explain the Optional class in Java.
- Implement Predicate, Consumer, and Function interfaces.
- Use method references in Java functional programming.
3.2 Overview
Functional programming is a modern programming approach that focuses on functions, immutability, and data processing using streams and lambda expressions. Java introduced functional programming features to simplify data processing and improve code readability.
This lesson introduces learners to functional programming concepts in Java and explains streams, lambda expressions, functional interfaces, and stream operations.
Functional programming is widely used in:
- enterprise applications,
- cloud systems,
- data processing,
- backend development,
- and modern Java frameworks.
Understanding functional programming is important because it simplifies complex operations and improves Java application development.
KT0301 — Functional Programming
Functional programming focuses on:
- functions,
- immutability,
- and data transformation.
The Value of Functions
Functions simplify:
- reusable logic,
- cleaner code,
- and data processing.
First Example with Function as Parameter
numbers.forEach(number ->
System.out.println(number));
Exercise — Loop a List of Numbers
List<Integer> numbers =
List.of(1, 2, 3, 4);
numbers.forEach(number ->
System.out.println(number));
Filtering — Exercises to Print Odd and Even Numbers
Even Numbers
numbers.stream()
.filter(number -> number % 2 == 0)
.forEach(System.out::println);
Odd Numbers
numbers.stream()
.filter(number -> number % 2 != 0)
.forEach(System.out::println);
Collect — Sum of Numbers in a List
int total = numbers.stream()
.reduce(0,
Integer::sum);
Functional Programming vs Structural Programming – A Quick Comparison
| Functional Programming | Structural Programming |
|---|---|
| Uses functions | Uses procedures |
| Focuses on immutability | Focuses on step-by-step logic |
| Uses streams/lambda | Uses loops and conditions |
Functional Programming Terminology
| Term | Meaning |
|---|---|
| Lambda Expression | Anonymous function |
| Stream | Sequence of data |
| Operation | Action on stream data |
Importance of Functional Programming
Functional programming improves:
- readability,
- scalability,
- and efficient data processing.
KT0302 — Stream Intermediate Operations
Intermediate operations transform streams without producing final results immediately.
Sort Operation
numbers.stream()
.sorted()
.forEach(System.out::println);
Distinct Operation
numbers.stream()
.distinct()
.forEach(System.out::println);
Filter Operation
numbers.stream()
.filter(number -> number > 5)
.forEach(System.out::println);
Map Operation
numbers.stream()
.map(number -> number * 2)
.forEach(System.out::println);
Importance of Intermediate Operations
Intermediate operations support:
- filtering,
- transformation,
- and stream processing.
KT0303 — Stream Terminal Operations
Terminal operations produce final results from streams.
max Operation with Comparator
numbers.stream()
.max(Integer::compare);
min Operation
numbers.stream()
.min(Integer::compare);
collect to List
List<Integer> results =
numbers.stream()
.collect(Collectors.toList());
Importance of Terminal Operations
Terminal operations:
- complete stream processing,
- generate results,
- and collect data.
KT0304 — Optional Class in Java – An Introduction
The Optional class helps avoid:
NullPointerException
by representing optional values safely.
Example
Optional<String> name =
Optional.of("John");
Benefits of Optional
Optional improves:
- null safety,
- readability,
- and safer programming.
KT0305 — Behind the Screens with Functional Interfaces
Functional interfaces contain only one abstract method.
Implement Predicate Interfaces
Predicate evaluates conditions.
Example
Predicate<Integer> isEven =
number -> number % 2 == 0;
Implement Consumer Interfaces
Consumer accepts values without returning results.
Example
Consumer<String> print =
text -> System.out.println(text);
Implement Function Interfaces
Function transforms values.
Example
Function<Integer, Integer> square =
number -> number * number;
Importance of Functional Interfaces
Functional interfaces support:
- lambda expressions,
- stream processing,
- and reusable functions.
KT0306 — Simplify Functional Programming Code with Method References
Method references simplify lambda expressions.
Lambda Example
numbers.forEach(number ->
System.out.println(number));
Method Reference Example
numbers.forEach(System.out::println);
Importance of Method References
Method references improve:
- readability,
- concise coding,
- and cleaner syntax.
KT0307 — Functions are First Class Citizens
In functional programming:
- functions can be passed,
- stored,
- and returned like data.
Functions are treated as reusable programming components.
Importance of First Class Functions
First class functions support:
- flexible design,
- reusable logic,
- and functional programming structures.
3.5 Key Notes / Summary
- Functional programming focuses on functions and immutability.
- Lambda expressions simplify function creation.
- Streams process collections efficiently.
- Intermediate operations transform streams.
- Terminal operations produce final results.
- Optional improves null safety.
- Functional interfaces support lambda expressions.
- Method references simplify functional programming syntax.