深入理解方法引用和构造器引用、数组构造器引用

一、方法引用和构造器引用的用途:
Lambda 表达式是可以简化函数式接口的变量或形参赋值的语法。而方法引用和构造器引用是为了简化 Lambda 表达式的。
二、方法引用
1、定义:方法引用可以看做是 Lambda 表达式深层次的表达。换句话说,方法引用就是Lambda 表达式,也就是函数式接口的一个实例,通过方法的名字来指向一个
方法,可以认为是 Lambda 表达式的一个语法糖。
2、语法糖:语法糖(Syntactic sugar),也译为糖衣语法,是由英国计算机科学家彼得·约翰·兰达(Peter J. Landin)发明的一个术语,指计算机语言中
   添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。通常来说使用语法糖能够增加程序的可读性,从而减少程序代码出错的机会。理解:
   往计算机语言语法中加糖,称为语法糖。
3、格式:类或对象::方法名
   格式说明:“::”两个冒号中间不能有空格
4、主要使用情况:
   情况一:对象::实例方法名
   情况二:类::静态方法名
   情况三:类::实例方法名
5、方法使用前提:
 (1)lambda体只有一句语句,并且是通过调用一个对象/类的现有的方法来完成的。
     案例:()->System.out.println();println()是现有的实例方法,System.out被看成了一个对象
 (2)针对情况一:函数式接口中的抽象方法 a 在被重写时使用了某一个对象的方法b。如果方法 a 的形参列表、返回值类型与方法 b 的形参列表、返回值类型都
     相同,则我们可以使用方法 b 实现对方法 a 的重写、替换。
 (3)针对情况二:函数式接口中的抽象方法 a 在被重写时使用了某一个类的静态方法 b。如果方法 a 的形参列表、返回值类型与方法 b 的形参列表、返回值类型
     都相同,则我们可以使用方法 b 实现对方法 a 的重写、替换。
 (4)针对情况三:函数式接口中的抽象方法 a 在被重写时使用了某一个对象的方法b。如果方法 a 的返回值类型与方法 b 的返回值类型相同,同时方法 a 的形参
     列表中有 n 个参数,方法 b 的形参列表有 n-1 个参数,且方法 a 的第 1 个参数作为方法 b 的调用者,且方法 a 的后 n-1 参数与方法 b 的 n-1 参
     数匹配(类型相同或满足多态场景也可以)。
6、举例:
import java.util.Comparator;
import java.util.function.Consumer;
import java.util.function.Supplier;

public class MethodRefTest {
    //情况一:对象::实例方法
    //Consumer函数式接口中的void accept(T t)方法
    //PrintStream类中的void println(T t)方法
    public void test(){
        //不使用lambda表达式
        Consumer<String> con=new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        };
        //使用lambda表达式重写接口方法
        Consumer<String> con1=str -> System.out.println(str);
        /*使用方法引用,函数式接口Consumer的抽象方法accept(T t)被重写时使用了方法println(),两个方法的形参类型都是String,返回值都是void,
        我们就用方法println()对方法accept(T t)进行重写和替换,前面是调用这个方法的对象System.out*/
        Consumer<String> con2=System.out::println;
    //情况二:类::静态方法
        //Comparator中的int compare(T t1,T t2);


        //不使用lambda表达式
        Comparator<Integer> com=new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return Integer.compare(o1,o2);//这里的Compare方法是静态方法
            }
        };
        //使用lambda表达式
        Comparator<Integer> com1=(o1, o2) ->Integer.compare(o1,o2);
        /*使用方法引用,函数式接口Compare(T t1,T t2)被重写时使用了Integer类的静态方法compare,两个形参类型一个是Interger,一个是int,两个
        /*类型会自动装箱、拆箱,类型一致,返回值类型都是int,则我们可以用静态方法compare对Compare(T t1,T t2)进行重写和替换。这里compare的
        调用者是类Integer
         */
        Comparator<Integer> com2=Integer::compare;
    //情况三:类::实例方法
        //Comparator中的int Compare(T t1,T t2)
        //使用lambda表达式
        Comparator<String> com3=(o1, o2) ->o1.compareTo(o2);//这里是对象调用
        /*使用方法引用,这里跟上面两种情况不同的是:方法Compare(String o1,String o2)有两个参数,方法compareTo(o2)这里只有一个参数,并且
        方法Compare(String o1,String o2)的第一个参数o1作为法compareTo(o2)的调用者,后面n-1个参数都是匹配的。所以可以用CompareTo方法对
        Compare(T t1,T t2)进行重写和替换。
         */
        Comparator<String> com4=String::compareTo;//本质上还是对象调用,只是格式简化而已
    }
}
7、说明:方法引用本质是对lambda表达式的简化,当我们拿到一个函数式接口时要马上想到他的抽象方法和我们要重写的方法是否符合方法引用三中情况,如果符合
   就可以跳过lambda表达式直接写出方法引用。
三、构造器引用
1、用途:当 Lambda 表达式是创建一个对象,并且满足 Lambda 表达式形参正好是给创建这个对象的构造器的实参列表,就可以使用构造器引用。
2、格式:类::new;
3、案例:
package Constructor;

import java.util.function.Supplier;

public class ConstructorRefTest {
    //构造器引用
    //supplier中的T get();
    //Employee中的空构造器
    public void test(){
        //lambda表达式
        Supplier<Employee> su1=()->new Employee();
        System.out.println(su1.get());
        //构造器引用
        Supplier<Employee> su2=Employee::new;
        System.out.println(su2.get());//上面构造器引用的是Employee众多构造器中的哪一个取决于这一句,这里没有形参,引用的是无形参的构造器
    }

    public static void main(String[] args) {
        ConstructorRefTest t=new ConstructorRefTest();
        t.test();
    }
}
四、数组构造引用
1、用途:当 Lambda 表达式是创建一个数组对象,并且满足 Lambda 表达式形参,正好是给创建这个数组对象的长度,就可以数组构造引用。
2、格式:数组类型名::new
3、举例:
public void test2(){
        //lambda表达式
        Function<Integer,String[]> f1=lenth ->new String[lenth];
        //数组构造引用
        Function<Integer,String[]> f2=String[]::new;
        System.out.println(f2.apply(5));
        System.out.println();
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值