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

本文用使用大量内置函数式接口,可参考上篇文章:java8新特性之函数式接口使用

1.使用场景

当要传递给Lambda体的操作,已经存在实现的方法了,就可以使用方法引用。(抽象方法的参数列表 必须与方法引用方法的参数列表保持一致),可以理解为lambda的另一种表现形式。

2. 语法

使用操作符【::】将方法名和对象或类的名字分开。三种主要使用情况:

1)对象::实例方法名
注:消费型接口,参数类型为String,返回值为void,System.out.println(x)的参数类型也是String,返回值也是void,可以使用方法引用写法

/**
 * lambda 方法引用
 * create by c-pown
 */
public class TestLambda {

      public static void main(String[] args) {
        //常规写法
        Consumer<String> consumer = (x) -> System.out.println(x);
        consumer.accept("张三");

        //方法引用写法
        Consumer<String> consum1 = System.out::println;
        consum1.accept("李四");
    }
}
张三
李四

2)类::静态方法名
注:消供给接口,参数类型为空,返回值为String,test1()的参数类型也是空,返回值也是String,可以使用方法引用写法

 public static void main(String[] args) {
      
        //调用静态方法
        //供给型接口,返回值为String
        //类名::方法   返回值与Supplier接口返回值一致
        Supplier<String> stringSupplier = TestLambda::test1;
        String s = stringSupplier.get();
        System.out.println(s);

    }

    public static String test1(){
        System.out.println("王五");
        return "王五";
    }

3)类::实例方法名
这种写法有点特别,BiPredicate接口有两个,参数第一个参数必须是方法的调用者,第二个参数是方法的穿餐,才能够书写。否则会报错。

	@Test
    public void test2(){
        //断言型几口子接口,传入两个参数,返回boolean
        BiPredicate<String,String> stringSupplier1 = String::contains;
        //类名::实例方法
        //要注意:这种写法,第一个参数必须是方法的调用者,第二个参数是方法的参数,才能够书写
        boolean test = stringSupplier1.test("abcde", "c");
        System.out.println(test);
    }
true

如果是普通方法,这种写法会报错。
在这里插入图片描述

二、构造器引用

语法:ClassName::new

 @Test
    public void test3(){
        //原写法
        Supplier<User> supplier = () -> new User();
        User user = supplier.get();
        System.out.println(user);

        //引用写法
        Supplier<User> supplier1 = User::new;
        User user1 = supplier1.get();
        System.out.println(user1);
    }
User{age=0, name='null', job='null'}
User{age=0, name='null', job='null'}

我们发现这种写法,只能够获取一个无参的构造器。如何能够获取一个有参数的构造器呢?

package entity;

public class User {

    private int age;

    private String name;

    private String job;

    public int getAge() {
        return age;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getJob() {
        return job;
    }

    public void setJob(String job) {
        this.job = job;
    }

    //一个参构造方法
    public User(int age) {
        this.age = age;
    }
	//无参构造方法
    public User() {
    }
    //有参构造方法
    public User(int age, String name, String job) {
        this.age = age;
        this.name = name;
        this.job = job;
    }

    @Override
    public String toString() {
        return "User{" +
                "age=" + age +
                ", name='" + name + '\'' +
                ", job='" + job + '\'' +
                '}';
    }
}
//一个参构造方法
    public User(int age) {
        this.age = age;
    }

我们在User类里面添加一个有一个参数的构造器。

Function<Integer,User> function = User::new;
User apply = function.apply(18);
System.out.println("一个参数构造器:"+apply);
User{age=0, name='null', job='null'}
User{age=0, name='null', job='null'}
一个参数构造器:User{age=18, name='null', job='null'}

使用Function函数传递一个Integer对象,发现调用的就是一个参数的构造器了。
参数的类型与个数,决定了调用的构造器是哪个。
在这里插入图片描述
如果对象没有当前类型构造器,使用构造器引用会报错。

展开阅读全文

Windows版YOLOv4目标检测实战:训练自己的数据集

04-26
©️2020 CSDN 皮肤主题: 岁月 设计师: pinMode 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值