Chapter 1. Java 8: why should you care?
1.1. Why is Java still changing?
1.1.1. Java’s place in the programming language ecosystem
1.1.3. Passing code to methods with behavior parameterization
1.2.1. Methods and lambdas as first-class citizens
Chapter 2. Passing code with behavior parameterization
2.1. Coping with changing requirements
2.1.1. First attempt: filtering green apples
2.1.2. Second attempt: parameterizing the color
2.1.3. Third attempt: filtering with every attribute you can think of
2.2. Behavior parameterization
2.3.2. Fifth attempt: using an anonymous class
2.4.1. Sorting with a Comparator
3.2. Where and how to use lambdas
3.3. Putting lambdas into practice: the execute around pattern
3.3.1. Step 1: Remember behavior parameterization
3.3.2. Step 2: Use a functional interface to pass behaviors
3.4. Using functional interfaces
3.5. Type checking, type inference, and restrictions
3.7. Putting lambdas and method references into practice!
3.7.2. Step 2: Use an anonymous class
3.8. Useful methods to compose lambda expressions
3.9. Similar ideas from mathematics
2. Functional-style data processing
Chapter 4. Introducing streams
4.2. Getting started with streams
Chapter 5. Working with streams
5.1.1. Filtering with a predicate
5.3.1. Checking to see if a predicate matches at least one element
5.5. Putting it all into practice
5.6.1. Primitive stream specializations
5.6.3. Putting numerical streams into practice: Pythagorean triples
Chapter 6. Collecting data with streams
6.5.1. Making sense of the methods declared by Collector interface
6.6. Developing your own collector for better performance
Chapter 7. Parallel data processing and performance
7.1.1. Turning a sequential stream into a parallel one
7.1.2. Measuring stream performance
7.2.1. Working with RecursiveTask
3. Effective Java 8 programming
Chapter 8. Refactoring, testing, and debugging
8.1. Refactoring for improved readability and flexibility
8.1.1. Improving code readability
8.1.2. From anonymous classes to lambda expressions
8.1.3. From lambda expressions to method references
8.2. Refactoring object-oriented design patterns with lambdas
8.3.1. Testing the behavior of a visible lambda
8.3.2. Focusing on the behavior of the method using a lambda
9.2. Default methods in a nutshell
9.3. Usage patterns for default methods
9.4.1. Three resolution rules to know
9.4.2. Most specific default-providing interface wins
Chapter 10. Using Optional as a better alternative to null
10.1. How do you model the absence of a value?
10.1.1. Reducing NullPointerExceptions with defensive checking
10.1.3. What are the alternatives to null in other languages?
10.2. Introducing the Optional class
10.3. Patterns for adopting Optional
10.3.1. Creating Optional objects
10.3.2. Extracting and transforming values from optionals with map
10.3.3. Chaining Optional objects with flatMap
10.3.4. Default actions and unwrapping an optional
10.4. Practical examples of using Optional
10.4.1. Wrapping a potentially null value in an optional
Chapter 11. CompletableFuture: composable asynchronous programming
11.1.2. Using CompletableFutures to build an asynchronous application
11.2. Implementing an asynchronous API
11.2.1. Converting a synchronous method into an asynchronous one
11.3. Make your code non-blocking
11.3.1. Parallelizing requests using a parallel Stream
11.3.2. Making asynchronous requests with CompletableFutures
11.4. Pipelining asynchronous tasks
11.4.1. Implementing a discount service
11.4.2. Using the Discount service
11.4.3. Composing synchronous and asynchronous operations
11.4.4. Combining two CompletableFutures—dependent and independent
11.5. Reacting to a CompletableFuture completion
Chapter 12. New Date and Time API
12.1. LocalDate, LocalTime, Instant, Duration, and Period
12.1.1. Working with LocalDate and LocalTime
12.1.2. Combining a date and a time
12.2. Manipulating, parsing, and formatting dates
12.3. Working with different time zones and calendars
Chapter 13. Thinking functionally
13.1. Implementing and maintaining systems
13.2. What’s functional programming?
13.2.2. Referential transparency
Chapter 14. Functional programming techniques
14.2. Persistent data structures
14.2.1. Destructive updates vs. functional
14.3. Lazy evaluation with streams
14.5.1. Caching or memoization
Chapter 15. Blending OOP and FP: comparing Java 8 and Scala
15.1.2. Basic data structures: List, Set, Map, Tuple, Stream, Option
15.2.1. First-class functions in Scala
Chapter 16. Conclusions and where next for Java
16.1. Review of Java 8 features
16.1.1. Behavior parameterization (lambdas and method references)
16.2.2. Type system enhancements
16.2.4. Richer forms of generics
Appendix A. Miscellaneous language updates
Appendix B. Miscellaneous library updates
Appendix C. Performing multiple operations in parallel on a stream
C.1.1. Implementing the Results interface with the ForkingStreamConsumer
C.1.2. Developing the ForkingStreamConsumer and the BlockingQueueSpliterator
Appendix D. Lambdas and JVM bytecode