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

    技术2022-07-10  97

    本文用使用大量内置函数式接口,可参考上篇文章: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对象,发现调用的就是一个参数的构造器了。 参数的类型与个数,决定了调用的构造器是哪个。 如果对象没有当前类型构造器,使用构造器引用会报错。

    Processed: 0.016, SQL: 9