目录
4.方法引用
思维导图
4.1 什么是方法引用
4.2 为什么要使用方法引用
4.3 方法引用语法
4.4 方法引用的5种情况使用示例
4.方法引用
思维导图
4.1 什么是方法引用
方法引用就是Lambda表达式,也就是函数式接口的一个实例,通过方法的名称来指向一个方法,可以认为是 Lambda表达式的一个语法糖
方法引用可以看作是Lambda表达式深层次的表达
当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用
4.2 为什么要使用方法引用
从前面学习中我们知道,Lambda 表达式已经简化了代码编写,那为什么还要有方法引用呢?
使用了方法引用后,代码更加简洁
下面以一个案例来演示Lambda表达式的冗余场景。
import java.util.function.Consumer; /** * 方法引用的引入 * 1. instanceName::methodName 实例对象::实例方法名 * 2. ClassName::staticMethodName 类名::静态方法名 * 3. ClassName::methodName 类名::实例方法名 * 4. ClassName::new 类名::构造方法名 * 5. TypeName[]::new 数组类型[]:数组构造器名 */ public class MethodReferenceDemo { public static void main(String[] args) { int[] arr = {1,2,3,4,5,6,7,8,9,}; sum1(arr); sum2((int[] ar) -> sum1(ar),arr); sum2(MethodReferenceDemo::sum1,arr); } /** * 使用Lambda表达式,求一个数组中元素的和 */ private static void sum1(int[] arr) { int sum = 0; for (int i : arr) { sum += i; } System.out.println("sum=" + sum); } private static void sum2(Consumer<int[]> consumer,int[] arr) { consumer.accept(arr); } }
此时,我们可以发现,使用了方法引用后,代码更加简洁了。
注意:上例中双冒号::写法,这被称为“方法引用”,是一种新的语法。4.3 方法引用语法
方法引用是使用双冒号::操作符来将类(或对象)与方法名分隔开来
使用方式有如下5种情况:
instanceName::methodName 实例对象::实例方法名
ClassName::staticMethodName 类名::静态方法名ClassName::methodName 类名::实例方法名
ClassName::new 类名::构造方法名TypeName[]::new 数组类型[]:数组构造器名
4.4 方法引用的5种情况使用示例
import java.util.Arrays; import java.util.Date; import java.util.function.BiFunction; import java.util.function.Function; import java.util.function.Supplier; /** * 方法引用的引入 * 1. instanceName::methodName 实例对象::实例方法名 * 2. ClassName::staticMethodName 类名::静态方法名 * 3. ClassName::methodName 类名::实例方法名 * 4. ClassName::new 类名::构造方法名 * 5. TypeName[]::new 数组类型[]:数组构造器名 */ public class MethodReferenceDemo1 { /** * 方法引用的使用实例 * */ public static void main(String[] args) { System.out.println("---1. instanceName::methodName 实例对象::实例方法名 ---"); test01(); System.out.println("---2. ClassName::staticMethodName 类名::静态方法名 ---"); test02(); System.out.println("---3. ClassName::methodName 类名::实例方法名 -----"); test03(); System.out.println("---4. ClassName::new 类名::构造方法名-----"); test04(); System.out.println("---5. TypeName[]::new 数组类型[]:数组构造器名-----"); test05(); } /** * 1. instanceName::methodName 实例对象::实例方法名 * * 方法引用的注意事项: * 1.被引用的方法,参数要和接口中抽象方法的参数一样, * 如 now:: setTime会报错,因为这个方法有参数,而Supplier接口的get()方法没有参数。 * 2.当接口抽象方法有返回值时,被引用的方法也必须有返回值 */ private static void test01() { // 创建一个对象 Date date = new Date(); //一般写法 System.out.println(date.getTime()); // Lambda表达式写法 Supplier<Long> supplier1 = () -> date.getTime(); System.out.println(supplier1.get()); // 方法引用写法 Supplier<Long> supplier2 = date::getTime; System.out.println(supplier2.get()); } /** * 2. ClassName::staticMethodName 类名::静态方法名 */ private static void test02() { //获取字符串长度 String str = "123456789"; //一般写法 System.out.println(str.length()); // Lambda表达式写法 Function<String,Integer> f1 = s -> s.length(); Integer apply1 = f1.apply(str); System.out.println(apply1); // 方法引用写法 Function<String,Integer> f2 = String::length; Integer apply2 = f2.apply(str); System.out.println(apply2); } /** * 3. ClassName::methodName 类名::实例方法名 */ private static void test03() { long l = System.currentTimeMillis(); //一般写法 System.out.println(l); // Lambda表达式写法 Supplier<Long> supplier1 = () -> System.currentTimeMillis(); System.out.println(supplier1.get()); // 方法引用写法 Supplier<Long> supplier2 = System::currentTimeMillis; System.out.println(supplier2.get()); } /** * 4. ClassName::new 类名::构造方法名 */ private static void test04() { //无参构造 // Lambda表达式写法 Supplier<User> supplier1 = () -> new User(); System.out.println(supplier1.get()); // 方法引用写法 Supplier<User> supplier2 = User::new; System.out.println(supplier2.get()); //有参构造 // Lambda表达式写法 BiFunction<String,Integer,User> bf1 = (name,age) -> new User(name,age); User user1 = bf1.apply("张三", 12); System.out.println(user1); // 方法引用写法 BiFunction<String,Integer,User> bf2 = User::new; User user2 = bf1.apply("李四", 13); System.out.println(user2); } /** * 5. TypeName[]::new 数组类型[]:数组构造器名 */ private static void test05() { // Lambda表达式写法 Function<Integer,int[]> f1 = len ->new int[len]; int[] apply1 = f1.apply(5); System.out.println(Arrays.toString(apply1)); // 方法引用写法 Function<Integer,int[]> f2 = int[]::new; int[] apply2 = f2.apply(6); System.out.println(Arrays.toString(apply2)); } }