The origin of Java lambda expressions

Java lambda expression

Introduction

I'm liitFeet, a server-side engineer. Recently, I feel like Coroutine WebFlux with kotlin and Spring Boot. Coroutine difficult ...

This article is the 7th day of TeamLab Engineering Advent Calendar.

In this article, I'll explain how Java lambda expressions work. Eh, now? There is a feeling like that, but now that I can handle functions such as go and kotlin as first-class citizens, I thought that it seems that I'm actually using lambda expressions without knowing what they are.

In conclusion, java lambda expressions implement an interface with only one method to create an instance (new). I don't think you can understand anything in this explanation, so I will explain the process up to the lambda expression in order, using a program that displays the result of calculating a certain expression as an example.

  1. Pass a normal class as an argument
  2. Pass the inner class as an argument
  3. Pass an anonymous class as an argument
  4. Pass the lambda expression as an argument

I think it's easy to understand if you are aware that lambda expressions are easy to read for both humans and compilers while reducing the amount of description.

Also, this article describes the origin of Java lambda expressions, Please note that we will not explain the lambda expression itself in detail (if there is only one argument, you do not need to write parentheses, functional interface, etc.).

The source code can be found on GitHub.

Pass a normal class as an argument

First of all, I would like to realize a program that displays the calculated result by passing a normal class. The source code is normalClass package. There are four sources below.

Main.java main class
Display.java Class to display the calculation result
CalcuratorInterface.Interface defined for java computation
Display.java                CalcuratorInterface

First, in the Display class, the calculator in charge of calculation and the value to be calculated (a, b) are received. Calculate and display the value of (a, b) with a calculator.

public class Display {
    public void showCalc(CalculatorInterface calculator, int a, int b) {
        System.out.println(calculator.calc(a, b));
    }
}

CalculatorInterface defines calc, a method that performs calculations.


public interface CalculatorInterface {
    int calc(int a, int b);
}

AddCalculator implements CalculatorInterface and returns the sum of the arguments (a, b).

public class AddCalculator implements CalculatorInterface {

    @Override
    public int calc(int a, int b) {
        return a + b;
    }
}

In the Main class, the calculation result is displayed by passing the calculated value to the Display class as `` `calculator```.

public class Main {
    public static void main(String[] args) {
        Display display = new Display();
        CalculatorInterface calculator = new AddCalculator();
        display.showCalc(calculator, 3, 5);
    }
}

I think there is no particular problem.

Handed over in inner class

Next, I would like to use the inner class. The source code is the innerClass package. CalcuratorInterface.java and Display.java are unchanged.

If you use the regular class mentioned above, don't you think it's a hassle to create a class file just for the addition that is used only for the Main class? Therefore, you can eliminate AddCalculator.java by defining AddCalculator in Main as shown below.

public class Main {
    public static void main(String[] args) {
        Display display = new Display();

        //Define inner class
        class AddCalculator implements CalculatorInterface {

            @Override
            public int calc(int a, int b) {
                return a + b;
            }
        }

        CalculatorInterface calculator = new AddCalculator();
        display.showCalc(calculator, 3, 5);
    }
}

Pass an anonymous class as a function

Next, we will use the anonymous class. The source code is the anonymousInnerClass package. I didn't have to create one class file using the inner class, but if I only use it once here, I don't need to name this class. Therefore, let's implement the class on the spot at the timing of assigning it to the calculator.

public class Main {
    public static void main(String[] args) {
        Display display = new Display();

        //Disposable once
        CalculatorInterface calculator = new CalculatorInterface() {
            @Override
            public int calc(int a, int b) {
                return a + b;
            }
        };
        display.showCalc(calculator, 3, 5);
    }
}

This is an anonymous class. It can't be reused, but the amount of description has gradually decreased.

Lambda expression

Finally, pass arguments using a lambda expression. The source code is lambdaExpression package. By using an anonymous class, I was able to omit the name of the class and reduce the amount of description. However, if you implement CalculatorInterface, it seems that the compiler will do it for you without writing `new CalculatorInterface ()`. Besides, if there is only one method, it is uniquely determined which method to implement. Method arguments are also type-defined in the interface, and the compiler can infer the type without declaring it.

In a lambda expression, you can create an instance by writing only the methods required for implementation.

public class Main {
    public static void main(String[] args) {
        Display display = new Display();

        //Only the processing of the method to be implemented
        CalculatorInterface calculator = (a, b) -> {
            return a + b;
        };

        display.showCalc(calculator, 3, 5);
    }
}

The lambda expression is the following part. This part represents the implementation of the calc method of CalculatorInterface.

(a, b) -> {
    return a + b;
};

(a, b)Is an argument. I don't bother to write the method argument because the type is defined in the interface. ->The following is the method implementation.a+bIs returning.

Summary

What did you think. I hope you can understand the meaning of writing "java lambda expression implements an interface with only one method and creates an instance (new)" at the beginning!

It's a complete digression, but it would be nice to be able to handle functions as first-class citizens like kotlin ... the arguments are easy to understand ...

val calculator = {a: Int, b: Int -> a + b}
showCalc(calculator, 3, 5)
fun showCalc(calc: (Int, Int) -> Int, a: Int, b: Int) {
  println(calc.invoke(a, b))
}

Recommended Posts

The origin of Java lambda expressions
Use Java lambda expressions outside of the Stream API
Understand Java 8 lambda expressions
Explain Java 8 lambda expressions
[Java] Summary of how to abbreviate lambda expressions
[Java] Summary of regular expressions
[Java] Introduction to lambda expressions
[Java Silver] Summary of points related to lambda expressions
[For beginners] Quickly understand the basics of Java 8 Lambda
[Java] Sort the list using streams and lambda expressions
Java lambda expressions learned with Comparator
[Java] Delete the elements of List
[Introduction to Java] About lambda expressions
[Java version] The story of serialization
About Lambda, Stream, LocalDate of Java8
How to use Java lambda expressions
A little understanding of lambda expressions
Examine the system information of AWS Lambda operating environment in Java
Find out the list of fonts available in AWS Lambda + Java
I tried the input / output type of Java Lambda ~ Map edition ~
Get the result of POST in Java
Name a group of regular expressions (Java)
Check the contents of the Java certificate store
Examine the memory usage of Java elements
Now let's recap the Java lambda expression
[Java] Get the day of the specific day of the week
Memo: [Java] Check the contents of the directory
Compare the elements of an array (Java)
[day: 5] I summarized the basics of Java
What are the updated features of java 13
Looking back on the basics of Java
Output of the book "Introduction to Java"
The story of writing Java in Emacs
[Java] Check the number of occurrences of characters
Hello Java Lambda
[Java] Lambda expression
[Java] Overview of Java
Java lambda expression
The story of low-level string comparison in Java
[Java] Handling of JavaBeans in the method chain
JAVA: jar, aar, view the contents of the file
The story of making ordinary Othello in Java
[Android] [Java] Manage the state of CheckBox of ListView
About the description order of Java system properties
About the idea of anonymous classes in Java
[Java] Access the signed URL of s3 (signed version 2)
The story of learning Java in the first programming
Measure the size of a folder in Java
[Java] Get the length of the surrogate pair string
[Java] The confusing part of String and StringBuilder
[Note] Java: Measures the speed of string concatenation
I compared the characteristics of Java and .NET
[Java] Be careful of the key type of Map
Calculate the similarity score of strings with JAVA
Try the free version of Progate [Java II]
[Java / Kotlin] Resize considering the orientation of the image
I touched on the new features of Java 15
The date time of java8 has been updated
[Java] How to get the authority of the folder
Import files of the same hierarchy in Java
First touch of the Files class (or Java 8)