Java8新特性之方法引用与构造器引用

方法引用

若Lambda体中的内容有方法已经实现了,我们可以使用“方法引用”,可以理解为方法引用是Lambda表达式的另外一种表现形式;其主要有三种语法格式:

  1. 对象::实例方法名
  2. 类::静态方法名
  3. 类::实例方法名

对象::实例方法名

我们上一篇写到Java8内置的几个接口,我们用到其中的一个消费型接口做一个例子:

 @Test
    public void test1() {
        
        Consumer<String> con = x -> System.out.println(x);
        
    }

其中我们最最常用的输出,println()方法其实也是一个实例方法:
在这里插入图片描述
那么我们可以套上我们前面说到的 对象::方法名 这样的格式:

PrintStream ps = System.out;
Consumer<String> con1= ps::println;

在这里插入图片描述
但是这样用法有一个限制:Lambda体中被调用的方法的参数列表与返回值类型必须要与这个接口中被实现的抽象方法的参数列表与返回时一致;这么看着有点绕,我们来看一下,我们Consumer< T>消费型接口的抽象方法是:
在这里插入图片描述
再看看我们被调用的实例方法:
在这里插入图片描述
这时候我们就可以用对象::实例方法名的方式调用;看一个反例吧,先来用上我们上一篇文章用到的Employee员工类:

package Lambda;

public class Employee {

    private String name;
    private int age;
    private double salary;

    public Employee() {
    }

    public Employee(String name, int age, double salary) {
        this.name = name;
        this.age = age;
        this.salary = salary;
    }

    public String getName() {
        return name;
    }


    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

    public void setName(String name) {
        this.name = name;
    }
    //测试用static方法
    public static void get(String s){
        System.out.println("haha");
    }

    @Override
    public String toString() {
        return "Employee{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", salary=" + salary +
                '}';
    }


}

然后我们来测试:
在这里插入图片描述
最后我们使用一下吧:
在这里插入图片描述

类::静态方法名

这种情况没什么特别,直接上代码

 @Test
    public void test3() {

        Comparator<Integer> comparable = (x, y) -> Integer.compare(x,y);
        
        Comparator<Integer> comparable1 = Integer::compareTo;

    }

类::实例方法名

首先我们找一个两个参数的函数式接口:
在这里插入图片描述
来看看例子:

@Test
    public void test4() {

        BiPredicate<String, String> bp = (x, y) -> x.equals(y);

        BiPredicate<String, String> bp1 = String::equals;

    }

诶很奇怪,equals方法明明是一个实例方法呀?
在这里插入图片描述
为什么能通过类名String直接调用呢?其实这是有一个规则的:
Lambda表达式中,如果第一个参数是这个实例方法的调用者,而第二个参数是这个实例方法的参数时,就能用ClassName::method这种方式;

构造器引用

格式:ClassName::new

先来看一个供给型接口的例子,看看普通Lambda表达式的调用:

   @Test
    public void test5() {
	
        Supplier<Employee> sup = () -> new Employee();
        Employee employee = sup.get();

    }

然后来进化一下,怎么用以上格式快捷引用构造器呢?

 @Test
    public void test5() {
        
        Supplier<Employee> sup1 = Employee::new;
        Employee employee = sup1.get();

    }

我们可以看到用了这种构造器引用方式之后会把参数列表省略了,那如果我们有多个不同参数列表的构造器,JVM怎么辨别出我们是想调用哪一个呢?这里也有一个重点:**所引用构造器的参数列表要跟函数式接口抽象方法中的参数列表一致。**那么以上get()方法就是调用了参数列表为空的构造器了,我们来验证一下:
在这里插入图片描述
我们试一下怎么调用不同参数列表的构造器,先来一个函数型接口,复习一下:在这里插入图片描述
我们先给它来一个,只有一个参数的构造器:
在这里插入图片描述
来看看怎么引用的:

 @Test
    public void test6() {
        Function<String, Employee> fun = (x) -> new Employee(x);
        Function<String, Employee> fun1 = Employee::new;

        Employee employee = fun1.apply("Kelvin");
        System.out.println(employee);
    }

测试结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值