[Java] Introduction to lambda expressions


To execute a thread in Java, use a subclass that inherits the Thread class, and There is a method using a subclass that implements the Runnable interface. This time, the latter is taken as an example for a brief explanation of the lambda expression.


public class Function implements Runnable{
	public void run() {
		//What to process in a thread


public class Main {
	public static void main(String[] args) {
		Thread thread = new Thread(new Function());

I think the output will look like this.


What is the relationship between the Thread class and the Runnable interface? The Strategy pattern design of the GoF design pattern is used. Roughly speaking, the Strategy pattern is designed to "realize a replaceable algorithm". The class that was originally one is in charge of the overall flow of processing, Let's divide it into classes that are in charge of specific algorithms. By using the Strategy pattern, with the user (Thread class) The side to be used (the class that realizes the Runnable interface) Since it does not have to be directly related, it is possible to realize an algorithm that can be replaced later. (For those who want to know more about Strategy patterns, see here) UML2.png However, the class that realized the interface is complicated (FunctionHard class in UML diagram). There is something like a class that requires simple code (FunctionEasy class in UML diagram).

New classes one by one, even with simple code Isn't it annoying to have to define? about it.

Lambda expression effectiveness

In order to solve the problem presented in the introduction, we will use the lambda expression introduced from Java SE 8. The following code replaces it with a lambda expression instead of creating a FunctionEasy class.


public class Lambda {
	public static void main(String[] args) {
		Runnable r = () -> System.out.println("hello!");
		Thread thread = new Thread(r);

You only need one line like this. Refreshing! Lambda expressions are "when instantiating a functional interface You can think of it as "a notation that does not require complicated writing."

An interface that has only one method that needs to be implemented is called a "functional interface" It is also called "SAM (Single Abstarct Method) interface".

As you can see from SAM, it has only one abstract method, so Which method does the lambda expression implement? What about arguments and return values? Inference is possible. There is no need to decide the method name one by one. Polymorphism can be realized without preparing a class that realizes the interface.

Anonymous classes and lambda expressions

Before Java8, it was realized by an anonymous class. Anonymous classes are sometimes called anonymous classes.

		Runnable r = new Runnable() {
			public void run() {

It's long and unreadable.

With the advent of lambda expressions in Java8, it's easier to write them.

		Runnable r = () -> {

A lambda expression declaration consists of an argument variable declaration and a processing block as shown below.

     (argument) -> {processing; };

"->" Is called an arrow operator.

Lambda abbreviation

Some lambda expressions can be omitted. Let's follow the following prototype as an example.


		Sample sample = (String a) -> { System.out.println(a);};

Abbreviation 1

If there is only one argument **, the parentheses "()" can be omitted. Also, the argument type can be inferred, so it can be omitted.

Abbreviation 1

		Sample sample = a -> { System.out.println(a);};

Abbreviation 2

Also, if the method body is one line, you can omit the curly braces "{}" and the semicolon ";" at the end of the sentence. In the case of return statement, return can also be omitted.

Abbreviation 2

		Sample sample = a -> System.out.println(a);

Abbreviation notation 3

In addition, if the argument can be inferred, the method call will Class name :: method name Object name :: method name It can be omitted like this.

Abbreviation notation 3

		Sample sample = System.out::println;

Variable scope of lambda expression

Note 1

** A variable with the same name as the local variable declared in the method cannot be used as the argument name of the lambda expression. ** ** The following will result in a compile error.

public class Sample {
	public static void main(String[] args) {
		String a = "sample";
		Function f = a -> System.out.println(a); //error

Since the variable name a has already been declared as a local variable, it cannot be used as an argument name for a lambda expression.

Note 2

** To access a local variable declared outside a lambda expression from within the lambda expression, the local variable must be final. If it does not have the final modifier, it must be practically final. ** **

You can access the local variables of the method that surrounds the expression from the lambda expression. (That's what it looks like before it's converted to a lambda expression.) You can access the local variables of the method that declares the expression from within the lambda expression as follows:

"Substantially final" means a variable that does not change even if it is not qualified with final. If you change the value of a local variable in a lambda expression as shown below, a compile error will occur.

public class Sample {
	public static void main(String[] args) {
		String a = "sample";
		Function f = () -> {
			a = "change"; //error

java.util.function package and Collection API

Frequently used functional interfaces are in the java.util.function package. In particular, the following five functional interfaces are famous.

Functional interface Method argument Return value Description
Consumer<T> void accept(T) Yes None "Consumer" who does not return a value
Supplier<T> T get() None Yes "Supplier" returning a value
Predicate<T> boolean test(T) Yes Yes "Affirmation" that returns a boolean value
Function<T, R> R apply(T) Yes Yes "Processing" that receives an argument and returns the result of the specified type
UnaryOperator<T> T apply(T t) There are two Yes "Operation" that returns the operation result

The Collection API has many default methods for manipulating List and Map.

For example, java.util.List has a method called * removeIf (Predicate filter) * to remove the element that matches the filter. If you use a lambda expression, you only need one line.


import java.util.ArrayList;
import java.util.Arrays;

public class RemoveIf {
	public static void main(String[] args) {

		ArrayList<String> list = new ArrayList<String>(Arrays.asList("aaaa", "bbb", "cc"));

		list.removeIf(v -> v.length() > 3);

		System.out.println(list); //result: [bbb, cc]

There are many other methods that allow you to specify a lambda expression. Let's investigate by yourself and implement it with a lambda expression to get used to it.


There are many web applications that run on Java 8 on the server side. Therefore, I think that the lambda expression & Stream API is inevitable knowledge when doing Java now. Nevertheless, it seems that there are some things that are not taught in Java newcomer training, so I tried to summarize it as easily as possible for newcomers. I'm sorry if there is a part that is difficult to understand.

Next time, I will summarize the introduction to Stream API around the next week.

(Updated December 22, 2019) Sequel Something → [Java] Introduction to Stream API

Recommended Posts

[Java] Introduction to lambda expressions
[Introduction to Java] About lambda expressions
[Java] Introduction to Java
Introduction to java
How to use Java lambda expressions
I tried to summarize Java lambda expressions
Understand Java 8 lambda expressions
About Java lambda expressions
Introduction to lambda expression
Explain Java 8 lambda expressions
Introduction to java command
[Java] Summary of how to abbreviate lambda expressions
[Java] Introduction to Stream API
[Introduction to rock-paper-scissors games] Java
[Java Silver] Summary of points related to lambda expressions
[Java] Introduction
Java lambda expressions learned with Comparator
[Introduction to Java] About Stream API
Introduction to Functional Programming (Java, Javascript)
Initial introduction to Mac (Java engineer)
Getting started with Java lambda expressions
The origin of Java lambda expressions
Introduction to SWING
Nowadays Java lambda expressions and Stream API
Introduction to algorithms with java --Search (depth-first search)
[Introduction to Java] How to write a Java program
Introduction to web3j
Introduction to Micronaut 1 ~ Introduction ~
Introduction to migration
Hello Java Lambda
[Java] Lambda expression
Output of the book "Introduction to Java"
Introduction to monitoring from Java Touching Prometheus
[Introduction to Java] Variable declarations and types
Easy to trip with Java regular expressions
Introduction to Doma
Java lambda expression
Introduction to Java Web Apps Performance Troubleshooting
Introduction to algorithms with java --Search (breadth-first search)
[Introduction to Java] About type conversion (cast, promotion)
Introduction to algorithms with java --Search (bit full search)
Road to Java Engineer Part1 Introduction & Environment Construction
How to use Java framework with AWS Lambda! ??
[Monthly 2017/04] Introduction to groovy !! ~ Java grammar / specification comparison ~
How to use Java API with lambda expression
Java8 to start now ~ forEach and lambda expression ~
An introduction to Groovy for tedious Java engineers
[Introduction to Java] Basics of java arithmetic (for beginners)
Java Performance Chapter 1 Introduction
Introduction to JAR files
Changes from Java 8 to Java 11
Sum from Java_1 to 100
Introduction to Ratpack (8)-Session
Introduction to RSpec 1. Test, RSpec
java neutral lambda expression 1
Introduction to Ratpack (6) --Promise
Quarkus saves Java Lambda! ??
Introduction to Ratpack (9) --Thymeleaf
[Java] Connect to MySQL
Java lambda expression variations
Introduction to PlayFramework 2.7 ① Overview