方法引用
-
举例: 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>() {@Overridepublic 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>() {@Overridepublic int compare(Integer o1, Integer o2) {return Integer.compare(o1, o2); // 兼容 int, 并且这是静态方法, 所以用类来引用, 泛型只能存放包装类型 }};System.out.println(com1.compare(12, 23)); // 前面小, 输出 -1System.out.println("=========================");// 2. lambdaComparator<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>() {@Overridepublic 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>() {@Overridepublic 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[]>() {@Overridepublic 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);
}
运行效果: