A Functional Approach to Java: Augmenting Object-Oriented Java Code with Functional Principles
معرفی کتاب «A Functional Approach to Java: Augmenting Object-Oriented Java Code with Functional Principles» نوشتهٔ Ben Weidig;، منتشرشده توسط نشر O'Reilly Media در سال 2023. این کتاب در فرمت pdf، زبان انگلیسی ارائه شده است. «A Functional Approach to Java: Augmenting Object-Oriented Java Code with Functional Principles» در دستهٔ بدون دستهبندی قرار دارد.
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 lambda expressions 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 into 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 this book, you will: Get a high-level overview of functional programming, including the types already available to Java developers Explore different FP concepts and learn how to use them Learn how to augment your code and use Java's new functional features in your daily work without going fully functional Develop a functional mindset and improve your programming skills regardless of language or paradigm Copyright 4 Table of Contents 5 Preface 13 New Hardware Needs a New Way of Thinking 14 Java Can Be Functional, Too 14 Why I Wrote This Book 16 Who Should Read This Book 16 What You Will Learn 17 What about Android? 18 A Functional Approach to Android 19 Navigating This Book 19 Conventions Used in This Book 20 Using Code Examples 21 O’Reilly Online Learning 21 Acknowledgments 22 Part I. Functional Basics 23 Chapter 1. An Introduction to Functional Programming 25 What Makes a Language Functional? 25 Functional Programming Concepts 28 Pure Functions and Referential Transparency 28 Immutability 29 Recursion 30 First-Class and Higher-Order Functions 30 Functional Composition 31 Currying 31 Partial Function Application 32 Lazy Evaluation 33 Advantages of Functional Programming 34 Disadvantages of Functional Programming 34 Takeaways 36 Chapter 2. Functional Java 37 What Are Java Lambdas? 37 Lambda Syntax 37 Functional Interfaces 39 Lambdas and Outside Variables 41 What about Anonymous Classes? 45 Lambdas in Action 48 Creating Lambdas 48 Calling Lambdas 50 Method References 50 Functional Programming Concepts in Java 54 Pure Functions and Referential Transparency 54 Immutability 57 First-Class Citizenship 58 Functional Composition 58 Lazy Evaluation 59 Takeaways 60 Chapter 3. Functional Interfaces of the JDK 61 The Big Four Functional Interface Categories 61 Functions 62 Consumers 62 Suppliers 63 Predicates 63 Why So Many Functional Interface Variants? 64 Function Arity 64 Primitive Types 66 Bridging Functional Interfaces 68 Functional Composition 69 Extending Functional Support 71 Adding Default Methods 71 Implementing Functional Interfaces Explicitly 73 Creating Static Helpers 74 Takeaways 78 Part II. A Functional Approach 79 Chapter 4. Immutability 81 Mutability and Data Structures in OOP 81 Immutability (Not Only) in FP 83 The State of Java Immutability 85 java.lang.String 85 Immutable Collections 87 Primitives and Primitive Wrappers 91 Immutable Math 91 Java Time API (JSR-310) 92 Enums 93 The final Keyword 93 Records 94 How to Achieve Immutability 95 Common Practices 96 Takeaways 97 Chapter 5. Working with Records 99 Data Aggregation Types 99 Tuples 99 A Simple POJO 100 From POJO to Immutability 102 From POJO to Record 104 Records to the Rescue 104 Behind the Scenes 105 Record Features 106 Missing Features 110 Use Cases and Common Practices 117 Record Validation and Data Scrubbing 118 Increasing Immutability 119 Creating Modified Copies 119 Records as Local Nominal Tuples 123 Better Optional Data Handling 126 Serializing Evolving Records 127 Record Pattern Matching (Java 19+) 130 Final Thoughts on Records 132 Takeaways 132 Chapter 6. Data Processing with Streams 135 Data Processing with Iteration 135 External Iteration 136 Internal Iteration 138 Streams as Functional Data Pipelines 139 Stream Features 143 Spliterator, the Backbone of Streams 147 Building Stream Pipelines 149 Creating a Stream 150 Doing the Work 151 Terminating the Stream 159 The Cost of Operations 173 Modifying Stream Behavior 176 To Use a Stream, or Not? 177 Takeaways 179 Chapter 7. Working with Streams 181 Primitive Streams 181 Iterative Streams 183 Infinite Streams 185 Random Numbers 186 Memory Isn’t Infinite 187 From Arrays to Streams and Back 188 Object-Type Arrays 189 Primitive Arrays 189 Low-Level Stream Creation 190 Working with File I/O 191 Reading Directory Contents 192 Depth-First Directory Traversal 192 Searching the Filesystem 194 Reading Files Line-By-Line 195 Caveats of File I/O Streams 197 Dealing with Date and Time 198 Querying Temporal Types 198 LocalDate-Range Streams 199 Measuring Stream Performance with JMH 199 More about Collectors 200 Downstream Collectors 201 Creating Your Own Collector 210 Final Thoughts on (Sequential) Streams 212 Takeaways 213 Chapter 8. Parallel Data Processing with Streams 215 Concurrency versus Parallelism 215 Streams as Parallel Functional Pipelines 217 Parallel Streams in Action 219 When to Use and When to Avoid Parallel Streams 222 Choosing the Right Data Source 222 Number of Elements 224 Stream Operations 224 Stream Overhead and Available Resources 228 Example: War and Peace (revisited) 229 Example: Random Numbers 230 Parallel Streams Checklist 233 Takeaways 234 Chapter 9. Handling null with Optionals 235 The Problem with null References 235 How to Handle null in Java (Before Optionals) 238 Best Practices for Handling null 239 Tool-Assisted null Checks 241 Specialized Types Like Optional 242 Optionals to the Rescue 242 What’s an Optional? 243 Building Optional Pipelines 246 Optionals and Streams 253 Optionals as Stream Elements 254 Terminal Stream Operations 255 Optional Primitives 257 Caveats 258 Optionals Are Ordinary Types 259 Identity-Sensitive Methods 259 Performance Overhead 260 Special Considerations for Collections 261 Optionals and Serialization 261 Final Thoughts on null References 262 Takeaways 263 Chapter 10. Functional Exception Handling 265 Java Exception Handling in a Nutshell 265 The try-catch block 266 The Different Types of Exceptions and Errors 266 Checked Exceptions in Lambdas 269 Safe Method Extraction 270 Un-Checking Exceptions 272 Sneaky Throws 273 A Functional Approach to Exceptions 275 Not Throwing Exceptions 275 Errors as Values 276 The Try/Success/Failure Pattern 281 Final Thoughts on Functional Exception Handling 288 Takeaways 289 Chapter 11. Lazy Evaluation 291 Laziness Versus Strictness 291 How Strict Is Java? 293 Short-Circuit Evaluation 293 Control Structures 294 Lazy Types in the JDK 295 Lambdas and Higher-Order Functions 297 An Eager Approach 297 A Lazier Approach 298 A Functional Approach 298 Delayed Executions with Thunks 300 Creating a Simple Thunk 300 A Thread-Safe Thunk 302 Final Thoughts on Laziness 305 Takeaways 306 Chapter 12. Recursion 307 What Is Recursion? 307 Head Versus Tail Recursion 309 Recursion and the Call Stack 310 A More Complex Example 311 Iterative Tree Traversal 313 Recursive Tree Traversal 314 Recursion-Like Streams 316 Final Thoughts on Recursion 316 Takeaways 318 Chapter 13. Asynchronous Tasks 319 Synchronous versus Asynchronous 319 Java Futures 320 Designing Asynchronous Pipelines with CompletableFutures 322 Promising a Value 323 Creating a CompletableFuture 323 Compositing and Combining Tasks 324 Exception Handling 328 Terminal Operations 330 Creating a CompletableFuture Helper 331 Manual Creation and Completion 336 Manual Creation 337 Manual Completion 337 Use Cases for Manually Created and Completed Instances 338 About Thread Pools and Timeouts 342 Final Thoughts on Asynchronous Tasks 343 Takeaways 344 Chapter 14. Functional Design Patterns 347 What Are Design Patterns? 347 (Functional) Design Patterns 348 Factory Pattern 348 Decorator Pattern 351 Strategy Pattern 357 Builder Pattern 359 Final Thoughts on Functional Design Patterns 364 Takeaways 365 Chapter 15. A Functional Approach to Java 367 OOP Versus FP Principles 367 A Functional Mindset 368 Functions Are First-Class Citizens 369 Avoiding Side Effects 370 Functional Data Processing with Map/Filter/Reduce 377 Abstractions Guide Implementations 378 Building Functional Bridges 379 Parallelism and Concurrency Made Easy 384 Be Mindful of Potential Overhead 385 Functional Architecture in an Imperative World 386 From Objects to Values 388 Separation of Concerns 388 The Different Sizes of an FC/IS 390 Testing an FC/IS 391 Final Thoughts on a Functional Approach to Java 392 Takeaways 394 Index 395 About the Author 405 Colophon 405 Java developers usually tackel the complexity of software development throught 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 provies easy-to-grasp FP tools such as lambda expressions 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 into 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
دانلود کتاب A Functional Approach to Java: Augmenting Object-Oriented Java Code with Functional Principles