A Functional Approach to Java: Augmenting Object-Oriented Java Code with Functional Principles
- Length: 400 pages
- Edition: 1
- Language: English
- Publisher: O'Reilly Media
- Publication Date: 2023-06-20
- ISBN-10: 1098109929
- ISBN-13: 9781098109929
- Sales Rank: #1215017 (See Top 100 Books)
Java developers usually tackle the complexity of software development through object-oriented programming (OOP). But not every problem is a good match for OOP. The functional programming (FP) paradigm offers you another approach to solving problems, and Java provides easy-to-grasp FP tools such as lambdas and streams. If you’re interested in applying FP concepts to your Java code, this book is for you.
Author Ben Weidig highlights different aspects of functional programming and shows you how to incorporate them in your code without going “fully functional.” You’ll learn how, when, and why to use FP concepts such as immutability and pure functions to write more concise, reasonable, and future-proof code. Many developers seek to expand their horizons by using OOP and FP together. It’s no longer either-or; it’s both.
In two parts, this book includes:
- A Functional Approach: Get a high-level overview of functional programming, including the types already available to Java developers. Then explore different FP concepts and learn how to use them.
- Real-World Problems, Patterns, and Recipes: Apply what you’ve learned in part one to the typical real-world problems you might encounter in your daily work.
Preface New Hardware Needs a New Way of Thinking Java Can Be Functional, Too Why I Wrote This Book Who Should Read This Book What You Will Learn What about Android? A Functional Approach to Android Navigating This Book Conventions Used in This Book Using Code Examples O’Reilly Online Learning Acknowledgments I. Functional Basics 1. An Introduction to Functional Programming What Makes a Language Functional? Functional Programming Concepts Pure Functions and Referential Transparency Immutability Recursion First-Class and Higher-Order Functions Functional Composition Currying Partial Function Application Lazy Evaluation Advantages of Functional Programming Disadvantages of Functional Programming Takeaways 2. Functional Java What Are Java Lambdas? Lambda Syntax Functional Interfaces Lambdas and Outside Variables Effectively final Re-finalizing a reference What about Anonymous Classes? Lambdas in Action Creating Lambdas Calling Lambdas Method References Static method references Bound non-static method references Unbound non-static method references Constructor references Functional Programming Concepts in Java Pure Functions and Referential Transparency Immutability First-Class Citizenship Functional Composition Lazy Evaluation Takeaways 3. Functional Interfaces of the JDK The Big Four Functional Interface Categories Functions Consumers Suppliers Predicates Why So Many Functional Interface Variants? Function Arity Primitive Types Bridging Functional Interfaces Functional Composition Extending Functional Support Adding Default Methods Implementing Functional Interfaces Explicitly Creating Static Helpers Takeaways II. A Functional Approach 4. Immutability Mutability and Data Structures in OOP Immutability (Not Only) in FP The State of Java Immutability java.lang.String Immutable Collections Unmodifiable Collections Immutable Collection factory methods Immutable copies Primitives and Primitive Wrappers Immutable Math Java Time API (JSR-310) Enums The final Keyword Records How to Achieve Immutability Common Practices Takeaways 5. Working with Records Data Aggregation Types Tuples A Simple POJO From POJO to Immutability From POJO to Record Records to the Rescue Behind the Scenes Record Features Component accessors Canonical, compact, and custom constructors Object identity and description Generics Annotations Reflection Missing Features Additional state Inheritance Component default values and convenience constructors Step-by-step creation Use Cases and Common Practices Record Validation and Data Scrubbing Increasing Immutability Creating Modified Copies Wither methods Builder pattern Tool-assisted builder Records as Local Nominal Tuples Better Optional Data Handling Ensure non-null container Add convenience constructors Serializing Evolving Records Record Pattern Matching (Java 19+) Final Thoughts on Records Takeaways 6. Data Processing with Streams Data Processing with Iteration External Iteration Internal Iteration Streams as Functional Data Pipelines Stream Features Lazy evaluation (Mostly) stateless and non-interfering Optimizations included Less boilerplate Non-reusable Primitive streams Easy parallelization (Lack of) Exception handling Spliterator, the Backbone of Streams Building Stream Pipelines Creating a Stream Doing the Work Selecting elements Mapping elements Peeking into a stream Terminating the Stream Reducing elements Aggregating elements with collectors Reducing versus collecting elements Aggregate elements directly Finding and matching elements Consuming elements The Cost of Operations Modifying Stream Behavior To Use a Stream, or Not? Takeaways 7. Working with Streams Primitive Streams Iterative Streams Infinite Streams Random Numbers Memory Isn’t Infinite From Arrays to Streams and Back Object-Type Arrays Primitive Arrays Low-Level Stream Creation Working with File I/O Reading Directory Contents Depth-First Directory Traversal Searching the Filesystem Reading Files Line-By-Line Caveats of File I/O Streams Explicit closing of the stream Weakly consistent directory content Non-guaranteed element order Dealing with Date and Time Querying Temporal Types LocalDate-Range Streams Measuring Stream Performance with JMH More about Collectors Downstream Collectors Transforming elements Reducing elements Flattening collections Filtering elements Composite collectors Creating Your Own Collector Final Thoughts on (Sequential) Streams Takeaways 8. Parallel Data Processing with Streams Concurrency versus Parallelism Streams as Parallel Functional Pipelines Parallel Streams in Action When to Use and When to Avoid Parallel Streams Choosing the Right Data Source Number of Elements Stream Operations Pure lambdas Parallel-friendly operations Reduce versus collect Stream Overhead and Available Resources Example: War and Peace (revisited) Example: Random Numbers Parallel Streams Checklist Takeaways 9. Handling null with Optionals The Problem with null References How to Handle null in Java (Before Optionals) Best Practices for Handling null Don’t initialize a variable to null Don’t pass, accept, or return null Check everything outside your control null is acceptable as an implementation detail When and when not to follow the rules Tool-Assisted null Checks Specialized Types Like Optional Optionals to the Rescue What’s an Optional? Building Optional Pipelines Creating an Optional Checking for and reacting to values Filtering and mapping Getting a (fallback) value Optionals and Streams Optionals as Stream Elements Terminal Stream Operations Finding an element Reducing to a single value Optional Primitives Caveats Optionals Are Ordinary Types Identity-Sensitive Methods Performance Overhead Special Considerations for Collections Optionals and Serialization Final Thoughts on null References Takeaways 10. Functional Exception Handling Java Exception Handling in a Nutshell The try-catch block The Different Types of Exceptions and Errors Checked exceptions Unchecked exceptions Errors Exception hierarchy in Java Checked Exceptions in Lambdas Safe Method Extraction Un-Checking Exceptions Sneaky Throws A Functional Approach to Exceptions Not Throwing Exceptions Errors as Values Creating the scaffold Making Result<V, E> functional The Try/Success/Failure Pattern Creating a pipeline Handling success and failure Running the pipeline Final Thoughts on Functional Exception Handling Takeaways 11. Lazy Evaluation Laziness Versus Strictness How Strict Is Java? Short-Circuit Evaluation Control Structures Lazy Types in the JDK Lazy Maps Streams Optionals Lambdas and Higher-Order Functions An Eager Approach A Lazier Approach A Functional Approach Delayed Executions with Thunks Creating a Simple Thunk A Thread-Safe Thunk Final Thoughts on Laziness Takeaways 12. Recursion What Is Recursion? Head Versus Tail Recursion Recursion and the Call Stack A More Complex Example Iterative Tree Traversal Recursive Tree Traversal Recursion-Like Streams Final Thoughts on Recursion Takeaways 13. Asynchronous Tasks Synchronous versus Asynchronous Java Futures Designing Asynchronous Pipelines with CompletableFutures Promising a Value Creating a CompletableFuture Compositing and Combining Tasks Compositing tasks Combining tasks Running more two CompletableFuture instances at once Exception Handling Data and error channel revisited Rejected either tasks Terminal Operations Creating a CompletableFuture Helper The helper scaffold Designing eachOf Improving the CompletableFutures helper Manual Creation and Completion Manual Creation Manual Completion Use Cases for Manually Created and Completed Instances CompletableFutures as return values Pending CompletableFuture pipelines About Thread Pools and Timeouts Final Thoughts on Asynchronous Tasks Takeaways 14. Functional Design Patterns What Are Design Patterns? (Functional) Design Patterns Factory Pattern Object-oriented approach A more functional approach Decorator Pattern Object-oriented approach A more functional approach Strategy Pattern Object-oriented approach A more functional approach Builder Pattern Object-oriented approach A more functional approach Final Thoughts on Functional Design Patterns Takeaways 15. A Functional Approach to Java OOP Versus FP Principles A Functional Mindset Functions Are First-Class Citizens Avoiding Side Effects Pure functions Pure object methods Isolating side effects Favor expressions over statements Moving toward immutability Functional Data Processing with Map/Filter/Reduce Abstractions Guide Implementations Building Functional Bridges Method references-friendly signatures Using retroactive functional interfaces Lambda factories for common operations Implementing functional interfaces explicitly Functional null handling with Optionals Parallelism and Concurrency Made Easy Be Mindful of Potential Overhead Functional Architecture in an Imperative World From Objects to Values Separation of Concerns The Different Sizes of an FC/IS Testing an FC/IS Final Thoughts on a Functional Approach to Java Takeaways Index
Donate to keep this site alive
How to download source code?
1. Go to: https://www.oreilly.com/
2. Search the book title: A Functional Approach to Java: Augmenting Object-Oriented Java Code with Functional Principles
, sometime you may not get the results, please search the main title
3. Click the book title in the search results
3. Publisher resources
section, click Download Example Code
.
1. Disable the AdBlock plugin. Otherwise, you may not get any links.
2. Solve the CAPTCHA.
3. Click download link.
4. Lead to download server to download.