winterbe / java8-tutorial
Modern Java - A Guide to Java 8
AI Architecture Analysis
This repository is indexed by RepoMind. By analyzing winterbe/java8-tutorial in our AI interface, you can instantly generate complete architecture diagrams, visualize control flows, and perform automated security audits across the entire codebase.
Our Agentic Context Augmented Generation (Agentic CAG) engine loads full source files into context on-demand, avoiding the fragmentation of traditional RAG systems. Ask questions about the architecture, dependencies, or specific features to see it in action.
Repository Overview (README excerpt)
Crawler viewModern Java - A Guide to Java 8 _This article was originally posted on my blog._ > **You should also read my Java 11 Tutorial (including new language and API features from Java 9, 10 and 11).** Welcome to my introduction to Java 8. This tutorial guides you step by step through all new language features. Backed by short and simple code samples you'll learn how to use default interface methods, lambda expressions, method references and repeatable annotations. At the end of the article you'll be familiar with the most recent API changes like streams, functional interfaces, map extensions and the new Date API. **No walls of text, just a bunch of commented code snippets. Enjoy!** --- ★★★ Like this project? Leave a star, follow on Twitter or donate to support my work. Thanks! ★★★ --- Table of Contents • Default Methods for Interfaces • Lambda expressions • Functional Interfaces • Method and Constructor References • Lambda Scopes • Accessing local variables • Accessing fields and static variables • Accessing Default Interface Methods • Built-in Functional Interfaces • Predicates • Functions • Suppliers • Consumers • Comparators • Optionals • Streams • Filter • Sorted • Map • Match • Count • Reduce • Parallel Streams • Sequential Sort • Parallel Sort • Maps • Date API • Clock • Timezones • LocalTime • LocalDate • LocalDateTime • Annotations • Where to go from here? Default Methods for Interfaces Java 8 enables us to add non-abstract method implementations to interfaces by utilizing the keyword. This feature is also known as virtual extension methods. Here is our first example: Besides the abstract method the interface also defines the default method . Concrete classes only have to implement the abstract method . The default method can be used out of the box. The formula is implemented as an anonymous object. The code is quite verbose: 6 lines of code for such a simple calculation of . As we'll see in the next section, there's a much nicer way of implementing single method objects in Java 8. Lambda expressions Let's start with a simple example of how to sort a list of strings in prior versions of Java: The static utility method accepts a list and a comparator in order to sort the elements of the given list. You often find yourself creating anonymous comparators and pass them to the sort method. Instead of creating anonymous objects all day long, Java 8 comes with a much shorter syntax, **lambda expressions**: As you can see the code is much shorter and easier to read. But it gets even shorter: For one line method bodies you can skip both the braces and the keyword. But it gets even shorter: List now has a method. Also the java compiler is aware of the parameter types so you can skip them as well. Let's dive deeper into how lambda expressions can be used in the wild. Functional Interfaces How does lambda expressions fit into Java's type system? Each lambda corresponds to a given type, specified by an interface. A so called _functional interface_ must contain **exactly one abstract method** declaration. Each lambda expression of that type will be matched to this abstract method. Since default methods are not abstract you're free to add default methods to your functional interface. We can use arbitrary interfaces as lambda expressions as long as the interface only contains one abstract method. To ensure that your interface meet the requirements, you should add the annotation. The compiler is aware of this annotation and throws a compiler error as soon as you try to add a second abstract method declaration to the interface. Example: Keep in mind that the code is also valid if the annotation would be omitted. Method and Constructor References The above example code can be further simplified by utilizing static method references: Java 8 enables you to pass references of methods or constructors via the keyword. The above example shows how to reference a static method. But we can also reference object methods: Let's see how the keyword works for constructors. First we define an example class with different constructors: Next we specify a person factory interface to be used for creating new persons: Instead of implementing the factory manually, we glue everything together via constructor references: We create a reference to the Person constructor via . The Java compiler automatically chooses the right constructor by matching the signature of . Lambda Scopes Accessing outer scope variables from lambda expressions is very similar to anonymous objects. You can access final variables from the local outer scope as well as instance fields and static variables. Accessing local variables We can read final local variables from the outer scope of lambda expressions: But different to anonymous objects the variable does not have to be declared final. This code is also valid: However must be implicitly final for the code to compile. The following code does **not** compile: Writing to from within the lambda expression is also prohibited. Accessing fields and static variables In contrast to local variables, we have both read and write access to instance fields and static variables from within lambda expressions. This behaviour is well known from anonymous objects. Accessing Default Interface Methods Remember the formula example from the first section? Interface defines a default method which can be accessed from each formula instance including anonymous objects. This does not work with lambda expressions. Default methods **cannot** be accessed from within lambda expressions. The following code does not compile: Built-in Functional Interfaces The JDK 1.8 API contains many built-in functional interfaces. Some of them are well known from older versions of Java like or . Those existing interfaces are extended to enable Lambda support via the annotation. But the Java 8 API is also full of new functional interfaces to make your life easier. Some of those new interfaces are well kn…