方法引用
-
举例: Integer :: compare
-
理解: 可以看作是基于lambda表达式的进一步简化
-
当需要提供一个函数式接口的实例时, 可以使用lambda表达式提供实例
- 当满足一定条件下, 可以使用方法引用or构造器引用替换lambda表达式
-
-
实质: 方法引用作为函数式接口的实例 (注: 需要熟悉所使用函数式接口中的抽象方法)
-
格式:
- 类(或 对象) :: 方法名
-
对象 :: 实例方法 (非静态方法)
- 要求: 函数式接口的抽象方法a与其内部实现时调用的对象的某个方法b的形参列表和返回值类型一致
-
类 :: 静态方法
- 要求: 函数式接口的抽象方法a与其内部实现时调用的类的某个静态方法b的形参列表和返回值类型一致
-
类 :: 实例方法
- 要求: 函数式接口的抽象方法a与其内部实现时调用的对象的某个方法b的返回值类型相同。同时, 抽象方法a有 n个参数, 方法b中有n-1个参数, 且抽象方法a的第一个参数作为方法b的调用者, 且抽象方法a的后n-1个参数与 方法b的后n-1个参数的类型相同
接下来的是代码的演示以及输出的结果
- 对象 :: 实例方法
// 1. 对象 :: 实例方法
@Test
public void test1(){
Consumer<String> con1 = new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
};
con1.accept("hello1");
System.out.println("===================");
// 2. lambda表达式 (只有一个形参时, 小括号可以省)
Consumer<String> con2 = s -> System.out.println(s);
con2.accept("hello2");
System.out.println("===================");
// 3. 对象 :: 调用方法
Consumer<String> con3 = System.out::println; // 只写方法名
con3.accept("hello3");
}
运行效果:
- 类 :: 静态方法
@Test
public void test2(){
// 1. 匿名函数
Comparator<Integer> com1 = new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return Integer.compare(o1, o2); // 兼容 int, 并且这是静态方法, 所以用类来引用, 泛型只能存放包装类型
}
};
System.out.println(com1.compare(12, 23)); // 前面小, 输出 -1
System.out.println("=========================");
// 2. lambda
Comparator<Integer> com2 = (o1, o2) -> Integer.compare(o1, o2);
System.out.println(com2.compare(23,21));
System.out.println("=========================");
// 3. 引用函数
Comparator<Integer> com3 = Integer :: compare;
System.out.println(com3.compare(23,11));
}
运行效果:
- 类 :: 实例方法
// 3. 类 :: 实例方法
@Test
public void test3(){
// 1.
Comparator<String> com1 = new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2); // 形参列表不一样, 返回值一样 1个参数调用 n-1为被调用的参数
}
};
System.out.println(com1.compare("abc","cdf"));
System.out.println("========================");
// 2. lambda表达式
Comparator<String> com2 = (o1, o2) -> o1.compareTo(o2); // 只是表达式有所差异, 执行速度一样
System.out.println(com2.compare("abb","abb"));
System.out.println("=====================");
// 3. 方法引用
Comparator<String> com3 = String::compareTo; // 返回值的类 :: 实例方法
System.out.println(com3.compare("ssa","aac")); // 第一个参数小, 返回负数; 相等 返回0; 第一个数大, 返回正数
}
运行效果:
构造器引用
可以看作是特殊的方法
-
格式: 类名 :: new
-
说明
- 调用类名对应的类中的某一个确定的构造器
- 调用哪一个构造器? 取决于函数式接口的抽象对象的形参列表
// 构造器引用
@Test
public void test1(){
//1.
Supplier<Employee> sup1 = new Supplier<Employee>() {
@Override
public Employee get() {
return new Employee(); // 构造器, 创建对象
}
};
System.out.println(sup1.get()); // 会调用无参构造
// 2. 方法引用
Supplier<Employee> sup2 = Employee :: new;
System.out.println(sup2.get());
}
Employee.java 就是拥有 age, id, name, salary属性以及构造器 setter, getter, toString方法的文件
运行效果:
数组引用
- 格式: 数组名[] :: new
@Test
public void test2(){
Function<Integer, Employee[]> func1 = new Function<Integer, Employee[]>() {
@Override
public Employee[] apply(Integer length) {
return new Employee[length];
}
};
System.out.println("============");
// 2. 数组引用
Function<Integer, Employee[]> fun2 = Employee[] :: new;
System.out.println(fun2.apply(100).length);
}
运行效果: