一、方法引用

1.理解:

方法引用可以看做是Lambda表达式深层次的表达。换句话说,方法引用就是Lambda表达式,也就是函数式接口的一个实例,通过方法的名字来指向一个方法。

2.使用情境:

当要传递给Lambda体的操作,已经实现的方法了,可以使用方法引用!

3.格式:

类(或对象) :: 方法名

4.分为如下的三种情况:

  • 情况1 对象 :: 非静态方法
  • 情况2 类 :: 静态方法
  • 情况3 类 :: 非静态方法

5.要求:

要求接口中的抽象方法的形参列表和返回值类型与方法引用的方法的形参列表和返回值类型相同!(针对于情况1和情况2)

当函数式接口方法的第一个参数是需要引用方法的调用者,并且第二个参数是需要引用方法的参数(或无参数)时:ClassName::methodName(针对于情况3)

6.使用建议:

如果给函数式接口提供实例,恰好满足方法引用的使用情境,大家就可以考虑使用方法引用给函数式接口提供实例。如果大家不熟悉方法引用,那么还可以使用lambda表达式。

7.使用举例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// 情况一:对象 :: 实例方法
//Consumer中的void accept(T t)
//PrintStream中的void println(T t)
@Test
public void test1() {
Consumer<String> con1 = str -> System.out.println(str);
con1.accept("北京");

System.out.println("*******************");
PrintStream ps = System.out;
Consumer<String> con2 = ps::println;
con2.accept("beijing");
}

//Supplier中的T get()
//Employee中的String getName()
@Test
public void test2() {
Employee emp = new Employee(1001,"Tom",23,5600);

Supplier<String> sup1 = () -> emp.getName();
System.out.println(sup1.get());

System.out.println("*******************");
Supplier<String> sup2 = emp::getName;
System.out.println(sup2.get());

}

// 情况二:类 :: 静态方法
//Comparator中的int compare(T t1,T t2)
//Integer中的int compare(T t1,T t2)
@Test
public void test3() {
Comparator<Integer> com1 = (t1,t2) -> Integer.compare(t1,t2);
System.out.println(com1.compare(12,21));

System.out.println("*******************");

Comparator<Integer> com2 = Integer::compare;
System.out.println(com2.compare(12,3));

}

//Function中的R apply(T t)
//Math中的Long round(Double d)
@Test
public void test4() {
Function<Double,Long> func = new Function<Double, Long>() {
@Override
public Long apply(Double d) {
return Math.round(d);
}
};

System.out.println("*******************");

Function<Double,Long> func1 = d -> Math.round(d);
System.out.println(func1.apply(12.3));

System.out.println("*******************");

Function<Double,Long> func2 = Math::round;
System.out.println(func2.apply(12.6));
}

// 情况:类 :: 实例方法 (难度)
// Comparator中的int comapre(T t1,T t2)
// String中的int t1.compareTo(t2)
@Test
public void test5() {
Comparator<String> com1 = (s1,s2) -> s1.compareTo(s2);
System.out.println(com1.compare("abc","abd"));

System.out.println("*******************");

Comparator<String> com2 = String :: compareTo;
System.out.println(com2.compare("abd","abm"));
}

//BiPredicate中的boolean test(T t1, T t2);
//String中的boolean t1.equals(t2)
@Test
public void test6() {
BiPredicate<String,String> pre1 = (s1,s2) -> s1.equals(s2);
System.out.println(pre1.test("abc","abc"));

System.out.println("*******************");
BiPredicate<String,String> pre2 = String :: equals;
System.out.println(pre2.test("abc","abd"));
}

// Function中的R apply(T t)
// Employee中的String getName();
@Test
public void test7() {
Employee employee = new Employee(1001, "Jerry", 23, 6000);


Function<Employee,String> func1 = e -> e.getName();
System.out.println(func1.apply(employee));

System.out.println("*******************");

Function<Employee,String> func2 = Employee::getName;
System.out.println(func2.apply(employee));


}

二、构造器引用

1.构造器引用格式

类名::new

2.构造器引用使用要求

和方法引用类似,函数式接口的抽象方法的形参列表和构造器的形参列表一致。抽象方法的返回值类型即为构造器所属的类的类型

3.构造器引用举例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
//Supplier中的T get()
//Employee的空参构造器:Employee()
@Test
public void test1(){

Supplier<Employee> sup = new Supplier<Employee>() {
@Override
public Employee get() {
return new Employee();
}
};
System.out.println("*******************");

Supplier<Employee> sup1 = () -> new Employee();
System.out.println(sup1.get());

System.out.println("*******************");

Supplier<Employee> sup2 = Employee :: new;
System.out.println(sup2.get());
}

//Function中的R apply(T t)
@Test
public void test2(){
Function<Integer,Employee> func1 = id -> new Employee(id);
Employee employee = func1.apply(1001);
System.out.println(employee);

System.out.println("*******************");

Function<Integer,Employee> func2 = Employee :: new;
Employee employee1 = func2.apply(1002);
System.out.println(employee1);

}

//BiFunction中的R apply(T t,U u)
@Test
public void test3(){
BiFunction<Integer,String,Employee> func1 = (id,name) -> new Employee(id,name);
System.out.println(func1.apply(1001,"Tom"));

System.out.println("*******************");

BiFunction<Integer,String,Employee> func2 = Employee :: new;
System.out.println(func2.apply(1002,"Tom"));

}

三、数组引用

1.数组引用格式

数组类型[] :: new

2.数组引用举例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//Function中的R apply(T t)
@Test
public void test4(){
Function<Integer,String[]> func1 = length -> new String[length];
String[] arr1 = func1.apply(5);
System.out.println(Arrays.toString(arr1));

System.out.println("*******************");

Function<Integer,String[]> func2 = String[] :: new;
String[] arr2 = func2.apply(10);
System.out.println(Arrays.toString(arr2));

}