From Collections to Streams in Java 8 Using Lambda Expressions
This course shows the new patterns introduced in Java 8, based on lambda expressions, the functional interfaces, the Collection Framework and the Stream API.
What you'll learn
Java 8 brought many new patterns to build efficient and clean applications. In this course, we cover one most important new thing: lambda expressions. Lambdas are a nice thing, but would be useless without new patterns to process data. These new patterns have been added to the Collection Framework, and to a the new Stream API. This course quickly explains what the map / filter / reduce pattern is about, and why is has been added to the Stream API. This new API is precisely described: how it can be used to efficiently process data and how it can be used in parallel. Caveats and corner cases are also shown.
Table of contents
- Introduction to the Course 3m
- What Are You Going to Learn in This Course? 2m
- Agenda of the Course 2m
- Who Are You? What Should You Know to Follow This Course? 2m
- Agenda of This Module 1m
- Lambda Expression: Introduction, Instances of Anonymous Classes 3m
- Lambda Expression: Passing Code as a Parameter 2m
- Let Us Write Our First, Simple Lambda Expressions 3m
- Lambda Expression: Remarks and Precisions 2m
- Method References: A First Example with an Instance Method 2m
- Method References: A Second Example with a Static Method 2m
- Method References: The System.out.println Pattern 2m
- How to Create New API: Default and Static Methods in Interfaces 2m
- Live Coding Introduction: The Comparator Example 1m
- Implementing a Comparator with Lambda Expressions 2m
- Comparing by Age, Last Name, and First Name 1m
- Refactoring the Comparison with a Key Extractor 2m
- Implementing the Comparator.comparing Static Method 3m
- Making the Key Extractor Generic, Returning Comparable Objects 2m
- Chaining Comparators with the thenComparing Default Method 2m
- Writing the Comparator.thenComparing Implementation 2m
- Writing the Final Comparator Creation and Chaining Pattern 3m
- Wrap-up of the Module 2m
- Version Check 0m
- Introduction to the Module 2m
- What Is a Functional Interface? The Predicate Example 2m
- How to Implement a Functional Interface with a Lambda Expression 2m
- How Does the Compiler Recognize the Type of a Lambda Expression? 4m
- A Lambda Is Still an Interface with Usable Methods 1m
- Functional Interface: The Complete and Exact Definition 3m
- How to Use the @FunctionalInterface Annotation 3m
- The Four Categories of the java.util.function Package 1m
- First Category: The Consumers 1m
- Second Category: The Supplier 1m
- Third Category: The Functions 3m
- Fourth Category: The Predicates 1m
- Functional Interfaces for Java Primitive Types 1m
- Introduction to the Live Coding Section: The Predicate Example 2m
- Writing and Using a First, Simple Predicate Lambda Expression 2m
- Chaining Predicates with the AND Boolean Operation 2m
- Adding a and() Method on the Predicate Functional Interface 2m
- Implementing the and() Default method on the Predicate Interface 4m
- Adding a or() Default Method on the Predicate Interface 3m
- Creating Predicates with a Static Call on a Functional Interface 3m
- Making the isEqualsTo() Method Generic of the Predicate Interface 2m
- Live Coding Wrap-up 1m
- Module Wrap-up, Presentation of the Next Module 2m
- Introduction to the Module 1m
- First Methods on Iterable, Collection and List 4m
- First Method on Map: forEach() 2m
- More Methods on Map: getOrDefault() 2m
- More Methods on Map: putIfAbsent() 3m
- More Methods on Map: replace() and replaceAll() 2m
- New Pattern on Map: remove() 1m
- New Patterns on Map: The compute() method 2m
- New Patterns on Map: computeIfAbsent(), computeIfPresent() 3m
- Building Maps of Maps and Maps of Lists with computeIfAbsent() 3m
- New Pattern on Map: The merge() method 2m
- Using merge() to Merge Two Maps Together 4m
- Live Coding Session Introduction, forEach() in Action 2m
- Methods removeIf(), replaceAll(), sort() in Action 3m
- Setting Default Value for map.get(): getOrDefault() 2m
- Adding Default key / value pairs: putIfAbsent, computeIfAbsent 3m
- Merging Maps with the map.merge() Method 3m
- Merging Maps: Analysis of the Result 2m
- Live Coding and Module Wrap-up 3m
- Introduction to the Module 1m
- Computing the Average of People Older than 20, Taken From a List 2m
- Map / filter / reduce: A Precise Explaination 3m
- A First Implementation, in the JDK7 Way 3m
- A Closer Look at the Reduction Step: How Does it Work? 2m
- Parallel Implementation of the Reduction Step 2m
- First Caveat: Non-associative Reduction Operations 4m
- How to Detect Non-associative Reduction Operations 3m
- Second Caveat: Reduction of a Singleton 3m
- Second Caveat: Reduction of a Set with Several Elements 3m
- Second Caveat: Reduction That Do Not Have Identity Element 1m
- Live Coding: Setting up the Environment 3m
- Simulating Parallel Computation of a Non-associative Reduction 4m
- Non-associative Reduction: The Average Reduction Operation 2m
- Computing a Max: Reduction with No Identity Element 2m
- Live Coding Wrap-up 1m
- Using Optionals to Handle Reductions with No Identity Element 1m
- Wrap-up on the Reduction Step 1m
- Implementation in the JDK7 Way: a Closer Look 1m
- CPU Load and Memory Footprint Evaluations 3m
- Example of an allMatch Reduction Operation: Lost Optimizations 2m
- Why Is this First, Naive Implementation Should be Avoided 2m
- A First Glimpse at the Stream API 2m
- Module Wrap-up 2m
- Introduction to the Module 1m
- A First Technical Definition of the Stream Interface 2m
- First Definitions of the Concept of Stream 2m
- The Notion of Unbounded Stream 2m
- How to Build Streams: Empty Streams, Singletons, varargs 3m
- How to Build Streams: The Generator and Iterator Pattern 2m
- How to Build Streams on Strings, Regular Expressions, and Text Files 3m
- The Stream.Builder Pattern 2m
- The map / filter / reduce Pattern Written with a Stream 3m
- A Second Example of the ap / filter / reduce Pattern on Streams 2m
- Intermediate and Terminal Calls on Streams: peek() and forEach() 3m
- How to Tell an Intermediate Call from a Terminal Call 2m
- Selecting Ranges of Data in Streams: skip() and limit() 3m
- Simple Reductions: Matchers, Short-circuiting Reductions 2m
- Finder Reductions, Use of Optionals 2m
- Example of Finder Reductions: findFirst(), findAny() 2m
- General Reductions: Use of the reduce() Method 4m
- Live Coding Session Introduction 1m
- Example of a First Simple Stream Built on a vararg 1m
- Building a Stream: The Generate Pattern, Use of Limit() 1m
- Building a Stream: The Iterate Pattern 2m
- Bulding Streams of Random Numbers Using Random.ints() 1m
- Live Coding Session Wrap-up 1m
- Module and Course Wrap-up 2m