Functional Programming Patterns
Functional programming concepts have transformed how we write clean Java code. This article covers pure functions, immutability, stream patterns, and how to apply functional thinking to make your code more readable, testable, and maintainable.
📋 At a Glance
| Aspect | Details |
|---|---|
| Concepts | Pure Functions, Immutability, Higher-Order Functions |
| Java Features | Streams, Optional, Lambdas, Method References |
| Benefits | Easier testing, no side effects, thread safety |
| Trade-offs | Learning curve, occasional performance overhead |
🎯 What You'll Learn
- Pure functions and why they matter
- Immutability patterns for safer code
- Stream patterns for clean data transformations
- Higher-order functions for reusable logic
- When to go functional vs imperative
Production Story: The Side Effect Bug
A payment reconciliation service had a bug that took weeks to find:
JAVA(17 lines)CodeLoading syntax highlighter...
runningTotal accumulated incorrectly.JAVA(15 lines)CodeLoading syntax highlighter...
Mental Model: Pure vs Impure Functions
TEXT(36 lines)CodeLoading syntax highlighter...
🔬 Deep Dive
Pattern 1: Pure Functions
JAVA(25 lines)CodeLoading syntax highlighter...
- Testable: No mocking required
- Cacheable: Same input = same output (memoization)
- Thread-safe: No shared mutable state
- Composable: Can chain without side effects
JAVA(19 lines)CodeLoading syntax highlighter...
Pattern 2: Immutability
JAVA(51 lines)CodeLoading syntax highlighter...
JAVA(19 lines)CodeLoading syntax highlighter...
Pattern 3: Stream Patterns
JAVA(40 lines)CodeLoading syntax highlighter...
JAVA(19 lines)CodeLoading syntax highlighter...
Pattern 4: Higher-Order Functions
JAVA(70 lines)CodeLoading syntax highlighter...
Pattern 5: Optional Patterns
JAVA(50 lines)CodeLoading syntax highlighter...
Pattern 6: Functional Pipeline
JAVA(55 lines)CodeLoading syntax highlighter...
Pattern 7: Collectors for Complex Aggregations
JAVA(53 lines)CodeLoading syntax highlighter...
⚠️ Common Mistakes
Mistake 1: Mixing Side Effects in Streams
JAVA(18 lines)CodeLoading syntax highlighter...
Mistake 2: Overusing Streams
JAVA(21 lines)CodeLoading syntax highlighter...
🐛 Debug This: The Stream Side Effect
A developer reports: "My parallel stream works fine in tests but produces inconsistent results in production!"
JAVA(37 lines)CodeLoading syntax highlighter...
Three major problems with parallel streams and shared mutable state:
ArrayListis not thread-safe - concurrentadd()calls can corrupt the list or lose elementsBigDecimalaccumulation is not atomic -totalRevenue = totalRevenue.add(...)is a read-modify-write operation that suffers from race conditions- Side effects in
forEach- parallel streams and side effects don't mix
JAVA(53 lines)CodeLoading syntax highlighter...
💻 Exercises
Exercise 1: Convert to Pure Function
⭐ Difficulty: Easy | ⏱️ Time: 10 minutes
JAVA(12 lines)CodeLoading syntax highlighter...
JAVA(25 lines)CodeLoading syntax highlighter...
Exercise 2: Stream Refactoring
⭐⭐ Difficulty: Medium | ⏱️ Time: 15 minutes
JAVA(32 lines)CodeLoading syntax highlighter...
JAVA(22 lines)CodeLoading syntax highlighter...
Exercise 3: Higher-Order Function
⭐⭐ Difficulty: Medium | ⏱️ Time: 20 minutes
JAVA(6 lines)CodeLoading syntax highlighter...
JAVA(67 lines)CodeLoading syntax highlighter...
Exercise 4: Immutable Builder
⭐⭐⭐ Difficulty: Medium-Hard | ⏱️ Time: 20 minutes
JAVA(10 lines)CodeLoading syntax highlighter...
JAVA(78 lines)CodeLoading syntax highlighter...
Exercise 5: Custom Collector
⭐⭐⭐⭐ Difficulty: Hard | ⏱️ Time: 25 minutes
JAVA(14 lines)CodeLoading syntax highlighter...
JAVA(73 lines)CodeLoading syntax highlighter...
🎤 Interview Questions
Q1: What makes a function "pure"?
- Same input always produces same output (deterministic)
- No side effects (doesn't modify external state)
- Doesn't depend on external mutable state
Benefits: Testable, cacheable, thread-safe, composable.
Q2: When should you prefer loops over streams?
- Complex control flow with early exit
- Need to track multiple mutable variables
- Index-based operations
- Performance-critical code with small collections
- Code clarity when stream chain becomes complex
📝 Summary
| Concept | Use When |
|---|---|
| Pure Functions | Calculations, transformations |
| Immutability | Value objects, DTOs, thread safety |
| Streams | Collection transformations, aggregations |
| Higher-Order Functions | Reusable cross-cutting logic |
| Optional | Return values that might be absent |
📅 Review Schedule for This Article
| Day | Task | Time |
|---|---|---|
| Day 1 | Review pure vs impure functions mental model | 5 min |
| Day 3 | Redo Exercise 2 (Stream Refactoring) | 15 min |
| Day 7 | Answer interview questions without looking | 10 min |
| Day 14 | Redo Debug This (Stream Side Effect) | 15 min |
| Day 30 | Find one impure function in your codebase to refactor | 20 min |