New feature of JDK 1.8 -- method reference

In the last article, we introduced the following new features of JDK 1.8.

1.Lambda expression

2. Method reference

3. Functional interface

4. Default method

5.Stream

6.Optional

7. Nansharm JavaScript engine

8. New date time API

9.Base64

And learned the most important features of JDK 1.8-- Lambda expression , a reference to this learning method.

 

What is method reference first?

Methods it's not difficult to understand the quotation. We often take Chairman Mao's saying that "no matter the black cat or the white cat can catch the mouse, the cat is a good cat." this is the quotation of Chairman Mao. Then method reference is to take methods that already exist in other places. Let's use them. It can be understood as a special usage of Lambda expression here. It's just that we have to follow certain rules. That is to say, what we will focus on next: the way of method reference

Next, I'll list the method references.

In general, there are three ways to reference methods, as follows.

  1. Common method reference
1.1 instance method reference (through instance object)
Object:: instance method name;
1.2 static method reference
Class name:: static method name;
1.3 instance method reference (by class name)
Class name:: instance method name;
Note: the differences between the above two instance methods are explained in detail in the following code.
  2. Constructor reference
Class name:: new;
  3. Array reference
Type:: new;

The following focuses on learning the above centralized form through examples.
1.1 instance method reference (through instance object)
The following is a simple printout statement to understand the instance method reference.
 1 public class MethodReferenceTest {
 2 
 3     /**
 4      * To make method references easier to understand
 5      * I implement the code part in two ways: normal Lambda expression and method reference
 6      */
 7     //*****************************
 8     // Method reference form one object::Instance method name
 9     //*****************************
10     @Test
11     public void test1(){
12         //Lambda expression
13         PrintStream ps1 = System.out;
14         Consumer con1 = x -> ps1.println(x);
15         con1.accept("Hello Lambda expression!");
16 
17         //Method reference
18         PrintStream ps2 = System.out;
19         Consumer con2 = ps2::println;
20         con2.accept("Hello Method reference!");
21     }
22 
23 }

results of enforcement

...
com.dream.test.JDK8speciality.MethodReferenceTest,test1 Hello Lambda expression! Hello Method reference! Process finished with exit code
0

It can be seen from the comparison of line 14 and line 19 of the above example that the way of using method reference is more concise than that of direct Lambda expression. Again, it can be seen that method reference is a special way of writing Lambda expression. After learning Lambda expression, the way of writing method reference is not difficult to understand.

Note: Consumer is JDK 1.8 java.util.function A functional interface is provided under the package. The accept method receives a generic < T > type and returns an abstract method with a void value. The specific implementation is implemented in the part of Lambda expression, that is, X - > ps1.println (x); and ps2::println; the functional interface provided by JDK 1.8 will be learned in the functional interface chapter later.

1.2 static method reference
The reference to a static method is understood by comparing the sizes of two integers.
 1 public class MethodReferenceTest {
 2 
 3     //*****************************
 4     // The formal second class name of method reference::Static method name
 5     //*****************************
 6     @Test
 7     public void test2(){
 8         //Lambda expression
 9         //x > y:Return 1;
10         //x = y:Return to 0;
11         //x < y:return-1;
12         Comparator<Integer> com1 = (x,y)->Integer.compare(x,y);
13         Integer i1=com1.compare(2,1);
14         System.out.println("Lambda Expression result:" + i1);
15 
16         //Method reference
17         Comparator<Integer> com2 = Integer::compare;
18         Integer i2=com2.compare(2,1);
19         System.out.println("Method reference result:" + i2);
20     }
21 
22 }

results of enforcement

com.dream.test.JDK8speciality.MethodReferenceTest,test2
 Lambda expression result: 1
 Method reference result: 1
 
Process finished with exit code 0

Normally, we (x, y) - > Integer.compare (x, y); in this way, since there are static methods under the integer class that have realized the comparison of two integers, we can directly refer to them through static method reference. This becomes Integer::compare;

1.3 instance method reference (by class name)
This is illustrated by comparing the contents of two strings.
 1 public class MethodReferenceTest {
 2 
 3     //*****************************
 4     // The formal three class names of method references::Instance method
 5     //*****************************
 6     @Test
 7     public void test3(){
 8         //Compare the contents of two strings
 9         //Lambda expression
10         BiPredicate<String,String> bp1 = (s1,s2) -> s1.equals(s2);
11         boolean b1 = bp1.test("abc","abc");
12         System.out.println("Lambda result:" + b1);
13 
14         //Method reference
15         BiPredicate<String,String> bp2 = String::equals;
16         boolean b2 = bp2.test("abc","abc");
17         System.out.println("Method results:" + b2);
18     }
19 
20 }

results of enforcement

...
com.dream.test.JDK8speciality.MethodReferenceTest,test3 Lambda result:
true //Method results:true Process finished with exit code 0

The difference between object reference and class name reference is that when the first parameter of the functional parameter list is the caller of the method and the second parameter is the parameter of the called method, we need to write the code in the way of class name: method name.

BiPredicate here is also JDK 1.8 java.util.function The function under the package is the interface. We will learn about the functional interface later in the functional interface chapter. Here we know it is the functional interface.

2. Constructor reference

Because constructors are used to create objects, the new keyword is also used here. That is, in the form of [class name:: new].

 1 public class MethodReferenceTest {
 2 //*****************************
 3     // Constructor reference class name::Instance method
 4     //*****************************
 5     @Test
 6     public void test4(){
 7         //Creating an object with a parameterless constructor
 8         System.out.println("Parameterless constructor");
 9         //Lambda expression
10         System.out.println("Lambda expression:");
11         Supplier<User> su1 =() -> new User();//Lambda Parentheses cannot be omitted when an expression has no arguments
12         User user1 = su1.get();
13         System.out.println("userName:" + user1.getUserName() + " pwd:" + user1.getPwd());
14 
15         //Constructor reference
16         System.out.println("Constructor reference:");
17         Supplier<User> su2 = User::new;
18         User user2 = su2.get();
19         System.out.println("userName:" + user2.getUserName() + " pwd:" + user2.getPwd());
20 
21         //Creating objects with a constructor with parameters
22         System.out.println("Parametric constructor");
23         //Lambda expression
24         System.out.println("Lambda expression:");
25         BiFunction<String,String,User> bf1 = (userName,pwd) -> new User(userName,pwd);
26         User user3 = bf1.apply("12345@163.com","987654321");
27         System.out.println("userName:" + user3.getUserName() + " pwd:" + user3.getPwd());
28 
29         //Constructor reference
30         System.out.println("Constructor reference:");
31         BiFunction<String,String,User> bf2 = User::new;
32         User user4 = bf2.apply("12345@163.com","987654321");
33         System.out.println("userName:" + user4.getUserName() + " pwd:" + user4.getPwd());
34 
35         /**
36          * By referring to the above examples of constructors with and without parameters, we can see that:
37          * No matter how many constructor parameters there are, the code of the reference part is ClassName::new, the difference is the functional interface.
38          */
39     }
40 
41 }

results of enforcement

...
com.dream.test.JDK8speciality.MethodReferenceTest,test4 Parameterless constructor Lambda expression: userName:null pwd:null Constructor reference: userName:null pwd:null Parametric constructor Lambda expression: userName:12345@163.com pwd:987654321 Constructor reference: userName:12345@163.com pwd:987654321 Process finished with exit code 0

With the understanding of the previous method references, it is not difficult to understand here. Just remember the form of the construction method reference. Note: when there is no parameter in Lambda expression, [() - >] must be written and cannot be omitted, otherwise an error will be reported.

Another point to note is that no matter how many parameters the constructor has, the reference form of the constructor is [class name:: constructor name]. The change uses different functional interfaces. The functional interface will be studied later in the functional interface chapter.

3. Array reference

The form of the array reference is similar to that of the constructor reference, but it just becomes [class name []: constructor name]. It doesn't have to be explained too much. Just look at the examples.

 1 public class MethodReferenceTest {
 2 
 3     //*****************************
 4     // Array reference type::new
 5     //*****************************
 6     @Test
 7     public void test5(){
 8         //Lambda expression
 9         Function<Integer,Integer[]> f1 =i -> new Integer[i];
10         Integer[] iArray1 = f1.apply(10);
11         System.out.println("Lambda expression: Array Count Reg" + iArray1.length);
12 
13         //Array reference
14         Function<Integer,Integer[]> f2 =Integer[]::new;
15         Integer[] iArray2 = f2.apply(10);
16         System.out.println("Array reference: Array Count Reg" + iArray2.length);
17     }
18 
19 }

results of enforcement

...
com.dream.test.JDK8speciality.MethodReferenceTest,test5 Lambda expression: Array length is 10 Array reference: array length is 10 Process finished with exit code 0

The functional interface is used here and will be explained in the next article.

 

The above is my understanding of method quotation. If there is any misunderstanding or bad writing, please let me know. Welcome to correct.

 

Last article

New features of JDK 1.8 (1) -- Lambda expression

Tags: Java Lambda JDK Javascript

Posted on Thu, 21 May 2020 09:22:27 -0700 by chick3n