![Functional Programming in Java: How functional techniques improve your Java programs](http://img.images-bn.com/static/redesign/srcs/images/grey-box.png?v11.9.4)
Functional Programming in Java: How functional techniques improve your Java programs
472![Functional Programming in Java: How functional techniques improve your Java programs](http://img.images-bn.com/static/redesign/srcs/images/grey-box.png?v11.9.4)
Functional Programming in Java: How functional techniques improve your Java programs
472eBook
Available on Compatible NOOK devices, the free NOOK App and in My Digital Library.
Related collections and offers
Overview
Functional Programming in Java teaches Java developers how to incorporate the most powerful benefits of functional programming into new and existing Java code. You'll learn to think functionally about coding tasks in Java and use FP to make your applications easier to understand, optimize, maintain, and scale.
Purchase of the print book includes a free eBook in PDF, Kindle, and ePub formats from Manning Publications.
About the Technology
Here's a bold statement: learn functional programming and you'll be a better Java developer. Fortunately, you don't have to master every aspect of FP to get a big payoff. If you take in a few core principles, you'll see an immediate boost in the scalability, readability, and maintainability of your code. And did we mention that you'll have fewer bugs? Let's get started!
About the Book
Functional Programming in Java teaches you how to incorporate the powerful benefits of functional programming into new and existing Java code. This book uses easy-to-grasp examples, exercises, and illustrations to teach core FP principles such as referential transparency, immutability, persistence, and laziness. Along the way, you'll discover which of the new functionally inspired features of Java 8 will help you most.
What's Inside
- Writing code that's easier to read and reason about
- Safer concurrent and parallel programming
- Handling errors without exceptions
- Java 8 features like lambdas, method references, and functional interfaces
About the Reader
Written for Java developers with no previous FP experience.
About the Author
Pierre-Yves Saumont is a seasoned Java developer with three decades of experience designing and building enterprise software. He is an R&D engineer at Alcatel-Lucent Submarine Networks.
Table of Contents
- What is functional programming?
- Using functions in Java
- Making Java more functional
- Recursion, corecursion, and memoization
- Data handling with lists
- Dealing with optional data
- Handling errors and exceptions
- Advanced list handling
- Working with laziness
- More data handling with trees
- Solving real problems with advanced trees
- Handling state mutation in a functional way
- Functional input/output
- Sharing mutable state with actors
- Solving common problems functionally
Product Details
ISBN-13: | 9781638353621 |
---|---|
Publisher: | Manning |
Publication date: | 01/18/2017 |
Sold by: | SIMON & SCHUSTER |
Format: | eBook |
Pages: | 472 |
File size: | 6 MB |
About the Author
Pierre-Yves Saumont is a seasoned Java developer with three decades of experience designing and building enterprise software. He is an R&D engineer at Alcatel-Lucent Submarine Networks.
Table of Contents
Preface xiii
Acknowledgments xvi
About this book xvii
1 What is functional programming? 1
1.1 What is functional programming? 2
1.2 Writing useful programs with no side effects 4
1.3 How referential transparency makes programs safer 6
1.4 The benefits of functional programming 7
1.5 Using the substitution model to reason about programs 8
1.6 Applying functional principles to a simple example 9
1.7 Pushing abstraction to the limit 14
1.8 Summary 15
2 Using functions in Java 16
2.1 What is a function? 17
Functions in the real world 17
2.2 Functions in Java 22
Functional methods 23
Java functional interfaces and anonymous classes 28
Composing functions 29
Polymorphic functions 29
Simplifying the code by using lambdas 31
2.3 Advanced function features 33
What about functions of several arguments? 33
Applying curried functions 34
Higher-order functions 35
Polymorphic higher-order functions 36
Using anonymous functions 39
Local functions 41
Closures 42
Partial function application and automatic currying 44
Sxoitching arguments of partially applied functions 48
Recursive functions 49
The identity function 51
2.4 Java 8 functional interfaces 52
2.5 Debugging with lambdas 53
2.6 Summary 56
3 Making Java more functional 57
3.1 Making standard control structures functional 58
3.2 Abstracting control structures 59
Cleaning up the code 63
An alternative to if… else 66
3.3 Abstracting iteration 71
Abstracting an operation on lists with mapping 72
Creating lists 73
Using head and tail, operations 74
Functionally appending to a list 75
Reducing and folding lists 75
Composing mappings and mapping compositions 82
Applying effects to lists 82
Approaching functional output 83
Building corecursive lists 84
3.4 Using the right types 87
Problems with standard types 87
Defining value types 90
The future of value types in Java 93
3.5 Summary 93
4 Recursion, corecursion, and memoization 94
4.1 Understanding corecursion and recursion 95
Exploring corecursive and recursive addition example 95
Implementing recursion in Java 96
Using tail call elimination 96
Using tail recursive methods and functions 97
Abstracting recursion 97
Using a drop-in replacement for stack-based recursive methods 101
4.2 Working with recursive functions 103
Using locally defined functions 104
Making functions tail recursive 104
Doubly recursive functions: the Fibonacci example 105
Making the list methods stack-safe and recursive 108
4.3 Composing a huge number of functions 111
4.4 Using memoization 114
Memoization in imperative programming 114
Memoization in recursive functions 115
Automatic memoization 117
4.5 Summary 123
5 Data handling with lists 124
5.1 How to classify data collections 125
Different types of lists 125
Relative expected list performance 126
Trading time against memory space, and time against complexity 127
In-place mutation 128
Persistent data structures 129
5.2 An immutable, persistent, singly linked list implementation 130
5.3 Data sharing in list operations 133
More list operations 135
5.4 Using recursion to fold lists with higher-order functions 140
Heap-based recursive version of fold-Right 146
Mapping and filtering lists 148
5.5 Summary 150
6 Dealing with optional data 151
6.1 Problems with the null pointer 152
6.2 Alternatives to null references 153
6.3 The Option data type 156
Getting a value from an Option 158
Applying functions to optional values 160
Dealing with Option composition 161
Option use cases 163
Other ways to combine options 167
Composing List with Option 169
6.4 Miscellaneous utilities for Option 171
Testing for Some or None 171
Equals and hashcode 172
6.5 How and when to use Option 172
6.6 Summary 175
7 Handling errors and exceptions 176
7.1 The problems to be solved 177
7.2 The Either type 178
Composing Either 179
7.3 The Result type 181
Adding methods to the Result class 183
7.4 Result patterns 184
7.5 Advanced Result handling 191
Applying predicates 191
Mapping failures 192
Adding factory methods 195
Applying effects 196
Advanced result composition 199
7.6 Summary 202
8 Advanced list handling 203
8.1 The problem with length 204
The performance problem 204
The benefit of memoization 205
The drawbacks of memoization 205
Actual performance 207
8.2 Composing List and Result 207
Methods on List returning Result 208
Converting from List <Result> to Result<List> 209
8.3 Abstracting common List use cases 212
Zipping and unzipping lists 212
Accessing elements by their index 215
Splitting lists 217
Searching for sublists 221
Miscellaneous functions for working with lists 222
8.4 Automatic parallel processing of lists 225
Not all computations can be parallelized 226
Breaking the list into sublists 226
Processing sublists in parallel 227
8.5 Summary 229
9 Working with laziness 230
9.1 Understanding strictness and laziness 230
Java is a strict language 231
The problem with strictness 232
9.2 Implementing laziness 233
9.3 Things you can't do without laziness 234
9.4 Why not use the Java 8 Stream? 235
9.5 Creating a lazy list data structure 236
Memoizing evaluated values 237
Manipulating streams 241
9.6 The true essence of laziness 243
Folding streams 245
9.7 Handling infinite streams 251
9.8 Avoiding null references and mutable fields 253
9.9 Summary 255
10 More data handling with trees 256
10.1 The binary tree 257
Balanced and unbalanced trees 258
Size, height, and depth 258
Leafy trees 259
Ordered binary trees or binary search trees (EST) 259
Insertion ender 260
Tree traversal order 261
10.2 Implementing the binary search tree 263
10.3 Removing elements from trees 268
10.4 Merging arbitrary trees 270
10.5 Folding trees 275
Folding with two functions 276
Folding with a single function 279
Winch fold implementation to choose 279
10.6 Mapping trees 281
10.7 Balancing trees 282
Rotating trees 282
Balancing trees using the Day-Stout-Warren algorithm 285
Automatically balancing trees 287
Solving the right-problem 288
10.8 Summary 288
11 Solving real problems with advanced trees 290
11.1 Better performance and stack safety with self-balancing trees 291
The basic tree, structure 291
Inserting an element into the red-black tree 295
11.2 A use case for the red-black tree: maps 300
Implementing Map 301
Extending maps 303
Using Map with n on comparable keys 304
11.3 Implementing a functional priority queue 307
The priority queue access protocol 307
Priority queue use cases 307
Implementation requirements 308
The leftist heap data structure 308
Implementing the leftist heap 309
Implementing the queue-like interface 313
11.4 A priority queue for noncomparable elements 314
11.5 Summary 319
12 Handling state mutation in a functional way 321
12.1 A functional random number generator 322
The random number generator interface 323
Implementing the random number generator 324
12.2 A generic API for handling state 327
Working with state operations 328
Composing state operations 329
Recursive state operations 331
12.3 Generic state handling 333
State patterns 334
Building a state machine 335
When to use state and the state machine 340
12.4 Summary 341
13 Functional input/output 342
13.1 Applying effects in context 343
What are effects? 343
Implementing effects 344
More-powerful effects for failures 346
13.2 Reading data 349
Reading data from the console 349
Reading from a file 354
Testing with input 355
13.3 Really functional input/output 356
How can input/output be made fully functional 356
Implementing purely functional input/output 357
Combining 10 358
Handling input with 10 359
Extending the 10 type 361
Making the 10 type stack-safe 364
13.4 Summary 369
14 Sharing mutable state with actors 370
14.1 The actor model 371
Asynchronous messaging 372
Handling parallelization 372
Handling actor state mutation 372
14.2 Building the actor framework 373
Limitations of this actor framework 374
Designing the actor framework interfaces 374
The AbstractActor implementation 376
14.3 Putting actors to work 377
Implementing the ping-pong example 378
A more serious example: running a computation in parallel 379
Reordering the results 385
Fixing the performance problem 388
14.4 Summary 393
15 Solving common problems functionally 394
15.1 Using assertions to validate data 395
15.2 Reading properties from file 399
Loading the property file 400
Reading properties as strings 400
Producing better error message 402
Reading properties as lists 405
Reading enum values 406
Reading properties of arbitral types 407
15.3 Converting an imperative program: the XML reader 409
Listing the necessary functions 411
Composing the functions and applying an effect 412
Implementing the functions 412
Making the program even more functional 414
Fixing the argument type problem 417
Making the element-processing function a parameter 418
Handling errors on element names 420
15.4 Summary 421
Appendix A Using Java 8 functional features 422
Appendix B Monads 429
Appendix C Where to go from here 434
Index 440