The first new feature of jdk1.8: "Lambda Expression"

Lambda expression

Sheep

Lambda expressions are a new feature introduced by JDK8, also known as anonymous functions or closures, that is, you can write the required code without creating displayed identifiers (function names, variable names, class names, etc.).

As an object-oriented language, java has strict requirements on grammar. In java, "everything is an object". But sometimes as we write more code, we find that writing java code sometimes becomes complicated. For example, we need to create a class every time we write code, and create an instance of this class when we use it. Sometimes we just need a function to achieve what we want, and don't want to bind it with any object. For example, define a method and use it directly when needed, just like the procedure-oriented function definition in C language. This is supported in C++ and Python, and it is not necessary to create a class every time when writing code.

The idea of ​​using the method directly is the idea of ​​functional programming. There is not much difference between "method" and "function" here. Many times, the term "method" is used in object-oriented programming languages, while "function" is more used in process-oriented programming languages, such as C Language. On an abstract level, "methods" and "functions" both accept user input, process data, and finally produce corresponding results.

In short, the Lambda expression introduced in JDK8 is to allow us to write more concise code in some cases. The following example illustrates

Use Lambda expressions

Complex code

In the method of creating multithreading, we have the following methods to create a thread, that is, to use the Runnable interface to rewrite the run method to achieve

Thread thread = new Thread(new Runnable() {
    
    
    @Override
    public void run() {
    
    
    	System.out.println("这是一个匿名内部类");
    }
});
thread.start();
//也可以
new Thread(new Runnable() {
    
    
    @Override
    public void run() {
    
    
    	System.out.println("这是一个匿名内部类");
    }
}).start();

Concise code

It can be found from the above that, in fact, our code only wants to execute System.out.println("This is an anonymous inner class"); this statement is only, but every time a thread is created, an implementation object of the Runnable interface needs to be created, because This is achieved in accordance with the "object-oriented" programming idea. If you use the Lambda expression method, the code is much more concise.

new Thread(()->{
    
    
	System.out.println("这是一个匿名内部类");
}).start();

Lambda syntax

The basic syntax of Lambda expression is as follows

() -> {}

(When I first learned it, I felt that the form is very similar to the arrow function in JS)

  1. The preceding pair of parentheses () are the parameters of the run method, where the run method itself does not need to pass any parameters.
  2. The middle - > means to pass the previous parameter to the code in the back {}
  3. {} means the code body executed by the run method

The standard format is:

(参数类型 参数名称...) -> {
    
    
	//方法执行的代码
}

Lambda expression omission

Lambda expressions can be further omitted in the above standard format. The possible omissions are as follows

  • The parameter types in parentheses can be omitted

    Java is a strongly typed language, and it is not allowed to omit parameter types in methods. However, the type of the parameter in the Lambda expression can be omitted, which is due to the speculation mechanism of java, which can be inferred from the context of the type of the variable.

  • If there is only one parameter in the parentheses, you can omit the parentheses; for example

    name -> {
          
          System.out.println(name);}
    

    I personally think that the program will be more readable when used with the above omission, that is, omit the variable type and brackets when there is only one parameter, and don't omit the variable type when there are multiple parameters.

  • If there is one and only one statement in the curly braces, regardless of whether there is a return value, you can omit the curly braces, the return keyword, and the semicolon of the statement; for example

    name -> System.out.println(name)
    

When to use Lambda expressions

Although the use of Lambda expressions can make the code more concise, but it is not arbitrarily can be used in any scenario. Just like the example above, it is used to replace the anonymous implementation class of the Runnable interface. That is to say, there is still an interface when it is used, and there is only one method in the interface. Otherwise , how do we know which method to call with a () ? Of course, it is worth mentioning that the anonymous implementation class will still create the class file of the class when it is compiled. Lambda expressions don't. Look at the decompilation method and find that Lambda expressions are encapsulated as a private method of the main class. For details, please see the article on java Lambda .

Similarly, the concept of a functional interface in the new features of JDK8 can be used well with Lambda expressions.

Functional interface

There is only one abstract method to be implemented in this interface (there can be some default methods). For example, the Runnable interface has only one run() method to be implemented. There is only one compare() method in the Comparator interface, and all other methods are decorated with default or static (except methods inherited from Object).

Examples of the interface definition

@FunctionalInterface
public interface MyFunctionInterface {
    
    
    public abstract void method();
}

The @FunctionalInterface annotation can be regarded as a functional interface at compile time. After adding this annotation, if multiple abstract methods are defined in the interface, an error will be reported. Adding this annotation can also make people very clear. It is a functional interface.

Use lambda to implement the method() method in this interface:

public class Demo {
    
    
    /*
    * 定义一个方法,将自定义的接口作为参数进行传递
    */
    public static void show(MyFunctionInterface myFunctionInterface) {
    
    
        myFunctionInterface.method();
    }

    public static void main(String[] args) {
    
    
        show(() -> {
    
    
            System.out.println("使用lambda表达式重写接口中的抽象方法!");
        });
    }
}

It can be seen that the use of Lambda expressions is generally to pass a functional interface as a parameter to a method (the construction method is also OK), and then use the Lambda expression to implement the abstract method corresponding to the interface.

Regarding functional interfaces, java defines some commonly used ones for us to use with Lambda, in the java.util.function package. I will talk about some commonly used functional interfaces later~

summary

  1. When the anonymous class is a functional interface, you can consider using Lambda expressions to simplify code writing;
  2. Although Lambda expression embodies the idea of ​​functional programming, Java still strictly uses object-oriented thinking, so Lambda expression cannot be used arbitrarily;
  3. Personally, I feel that the emergence of Lambda expressions is a huge step forward for Java to "write less, do more".

Guess you like

Origin blog.csdn.net/weixin_44184990/article/details/108393508