Lambda Expressions - Instructions for Use

   jdk8 has been released for 4 years, and there is one feature: Lambda, which is a way to facilitate developers to develop, Lambda Expression (Lambda expression) is to allow java to provide a function-oriented programming, originally only supported before jdk8 Object-Oriented Programming,

Functional programming, on the other hand, is an abstraction of behavior (passing the behavior as a parameter), which is illustrated by an example:

Here's an example of a thread object, passing in an anonymous inner class:

new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("Hello World!");
    }
});

IDEA will give a hint that lambda expressions can be used to replace.

By using lambda expressions, you only need to use one sentence to replace the above method of using anonymous classes.

new Thread(() -> System.out.println("Hello World!"));

  

In this example, according to the traditional grammar rules, we pass an anonymous inner class as a parameter, we implement the Runnable interface, and pass it as a parameter to the Thread class. In fact, what we pass is a piece of code, that is, We pass code as data, which brings a lot of unnecessary "boilerplate code".

  A lambda expression consists of three parts:

  In the following examples, we will explain this structure in detail, including whether there are parameters and whether there are return values. So what is the meaning of this strange-looking syntax rule that doesn't look very much like Java? This is also the question that started to bother me, when and in what scenarios can I use Lambda expressions.

  The parameter type that can receive a lambda expression is an interface that contains only one method. An interface that contains only one method is called a " functional interface ".

  For example, in the above example of creating a thread, the Runnable interface contains only one method, so it is called a "functional interface", so it can use Lambad expressions instead of anonymous inner classes. According to this rule, we try to write a functional interface and pass it as a parameter using a lambda expression.

copy code
1 package com.coderbuff.custom;
2
3 /**
4 * Functional interface: an interface with only one method. as the type of a lambda expression
5  * Created by Kevin on 2018/2/17.
6  */
7 public interface FunctionInterface {
8     void test();
9 }
copy code

   test:

copy code
1 package com.coderbuff.custom;
 2
 3 import org.junit.Test;
 4
 5 /**
 6 * Function interface test
 7  * Created by Kevin on 2018/2/17.
 8  */
 9 public class FunctionInterfaceTest {
10
11     @Test
12     public void testLambda() {
13         func(new FunctionInterface() {
14             @Override
15             public void test() {
16                 System.out.println("Hello World!");
17             }
18         });
19 //Use a Lambda expression instead of the anonymous inner class above
20         func(() -> System.out.println("Hello World"));
21     }
22
23     private void func(FunctionInterface functionInterface) {
24         functionInterface.test();
25     }
26 }
copy code

  It can be seen that as long as an interface contains only one method, Lambda expressions can be used. Such an interface is called a "functional interface".

  The above function interface is relatively simple and does not contain parameters and return values .

  Let's modify the FunctionInterface function interface to gradually increase the difficulty of Lambda expressions - including parameters, but not return values .

copy code
1 package com.coderbuff.custom;
2
3 /**
4 * Functional interface: an interface with only one method. as the type of a lambda expression
5  * Created by Kevin on 2018/2/17.
6  */
7 public interface FunctionInterface {
8     void test(int param);
9 }
copy code

  test:

copy code
1 package com.coderbuff.custom;
 2
 3 import org.junit.Test;
 4
 5 /**
 6 * Function interface test
 7  * Created by Kevin on 2018/2/17.
 8  */
 9 public class FunctionInterfaceTest {
10
11     @Test
12     public void testLambda() {
13 //Use Lambda expressions instead of anonymous inner classes
14         func((x) -> System.out.println("Hello World" + x));
15     }
16
17     private void func(FunctionInterface functionInterface) {
18         int x = 1;
19         functionInterface.test(x);
20     }
21 }
copy code

  Pay attention to the Lambda expression "(x) -> Sysout.out.println("Hello World" + x)", the parameter is passed on the left, and the parameter type is not specified here, because it can be deduced through the context, but in In some cases, the parameter type cannot be deduced (the IDE will usually prompt if it cannot be deduced at compile time), in this case, the parameter type needs to be specified. My personal recommendation is to specify the parameter type of the function in any case .

  In which case the parameter type cannot be deduced? That is when the functional interface is a generic type.

copy code
1 package com.coderbuff.custom;
2
3 /**
4 * Functional interface: an interface with only one method. as the type of a lambda expression
5  * Created by Kevin on 2018/2/17.
6  */
7 public interface FunctionInterface<T> {
8     void test(T param);
9 } 
copy code

  test:

copy code
1 package com.coderbuff.custom;
 2
 3 import org.junit.Test;
 4
 5 /**
 6 * Function interface test
 7  * Created by Kevin on 2018/2/17.
 8  */
 9 public class FunctionInterfaceTest {
10
11     @Test
12     public void testLambda() {
13 //Use Lambda expressions instead of anonymous inner classes
14         func((Integer x) -> System.out.println("Hello World" + x));
15     }
16
17     private void func(FunctionInterface<Integer> functionInterface) {
18         int x = 1;
19         functionInterface.test(x);
20     }
21 }
copy code

  The above example mentions two cases of Lambda expressions:

  No parameters, no return value;

  There are parameters, no return value.

  The next step is the more complicated case of parameters and return values .

copy code
1 package com.coderbuff.custom;
2
3 /**
4 * Functional interface: an interface with only one method. as the type of a lambda expression
5  * Created by Kevin on 2018/2/17.
6  */
7 public interface FunctionInterface<T> {
8     boolean test(T param);
9 }
copy code

   test:

copy code
1 package com.coderbuff.custom;
 2
 3 import org.junit.Test;
 4
 5 /**
 6 * Function interface test
 7  * Created by Kevin on 2018/2/17.
 8  */
 9 public class FunctionInterfaceTest {
10
11     @Test
12     public void testLambda() {
13 //Use Lambda expressions instead of anonymous inner classes
14         func((Integer x) -> true);
15     }
16
17     private void func(FunctionInterface<Integer> functionInterface) {
18         int x = 1;
19         functionInterface.test(x);
20     }
21 }
copy code

  At this time, the Lambda expression "(Integer x) -> true", the right side is the body of the expression, and returns true directly. If there are multiple lines of code, you can use curly braces directly, for example:

func((Integer x) -> {
    System.out.println("Hello World" + x);
    return true;
});

  Basic syntax rules for lambda expressions:

  No parameters, no return value;

  There are parameters, no return value;

  There are parameters and return values.

  These three basic situations have been roughly clarified. In particular, it is necessary to clarify when lambda expressions can be used to replace anonymous inner classes, that is, the application scenario of lambda expressions is functional interface. The introduction of the new feature of Lambda expression in JDK8, the greater benefit is the update of the collection API, the new Stream class library, so that we no longer use the for loop as before when traversing the collection.

 

Correct posture for using collections in JDK8

  Example: Count the number of students from "chengdu".

  Code before JDK8:

for (Student student : studentList) {
    if (student.getCity().equals("chengdu")) {
        count++;
    }
}

  The correct posture for JDK8 to use collections:

count = studentList.stream().filter((student -> student.getCity().equals("chengdu"))).count();

  The "difficulty" of using the API seems to have increased, but in fact it is just unfamiliar. The traditional iterative method needs to read the entire loop to understand the code logic, while the JDK8 method through the stream can be literally and the code size is greatly reduced.

  The most important of which is the Stream stream. Stream is a tool for performing complex operations on collection classes through functional programming. If I want to explain the implementation of Stream in detail, I believe it is not an exaggeration to write another blog, so I will not examine the internal implementation of Stream here. Here is to tell you that if you are fortunate enough to use the JDK8 development environment for development, try to learn to use the new collection operation API.

 There are too many applications of Lambda expressions, concurrent programming, reactive programming, etc.

 

Quoted in this article: http://www.cnblogs.com/yulinfeng/p/8452379.html

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325240127&siteId=291194637