lambda表达式的方法引用

·  阅读 87

这是我参与8月更文挑战的第24天,活动详情查看:8月更文挑战

方法引用可以让我们的代码更简洁一点

先写一个最简单的lambda表达式

    public static void main(String[] args) {
        Consumer<String> consumer = s-> System.out.println(s);
    }
复制代码

lambda表达式实际上是一个匿名参数,箭头左边是方法参数,右边是执行体,当函数执行体只有一个参数,且为传入的参数,就可以缩写成方法引用

public static void main(String[] args) {
    Consumer<String> consumer =  System.out::println;
}
复制代码

现在没有任何输出值,但是是通过的

Consumer<String> consumer =  System.out::println;
consumer.accept("看看结果");
复制代码

image.png

静态方法的方法引用

class Dog{
    private String name = "闪电";

    public static void bark(Dog dog){
        System.out.println(dog + "还活着");
    }

    @Override
    public String toString() {
        return this.name;
    }
}
public class MethodRefrenceDemo {
    public static void main(String[] args) {
        Consumer<String> consumer =  System.out::println;
        consumer.accept("回到小时候看到");
       
//静态方法的方法引用

        Consumer<Dog> consumer2 = Dog::bark;
        Dog dog = new Dog();
        consumer2.accept(dog);
    }
}
复制代码

image.png

以上输入是一个dog 的实例,输出为空,所以是一个静态方法

非静态方法

class Dog{
    private String name = "闪电";
    private int food = 10; //10斤骨头

    public static void bark(Dog dog){
        System.out.println(dog + "还活着");
    }

    //吃骨头
    public int eat(int num){
        System.out.println("喂给它"+ num +"斤骨头");
        this.food = food - num;
        return this.food;
    }

    @Override
    public String toString() {
        return this.name;
    }
}
public class MethodRefrenceDemo {
    public static void main(String[] args) {
        Consumer<String> consumer =  System.out::println;
        consumer.accept("回到小时候看到");

        //静态方法的方法引用
        //等号
        Consumer<Dog> consumer2 = Dog::bark;
        Dog dog = new Dog();
        consumer2.accept(dog);

        //非静态方法,使用对象实例来引用
        Function<Integer,Integer> function = dog::eat;
        System.out.println("还剩下"+function.apply(2)+"斤");

    }
}
复制代码

image.png

这里发现

Function<Integer,Integer> function = dog::eat;
复制代码

方法输入和输出接口都是一样的,所以我们可以合并成一个一元接口

UnaryOperator<Integer> function = dog::eat;
复制代码

因为类型时基本的Integer类型 ,所以得到了很多官方的支持就可以携程下面的样子

IntUnaryOperator function = dog::eat;
System.out.println("还剩下"+function.applyAsInt(2)+"斤");
复制代码

我们发现 无论是静态还是非静态,我们都用了 dog::eat

那么静态方法和成员方法去别是啥? 静态使用了 this.name而,成员方法没有,实际上java执行的时候默认 将函数的参数加进去了。

Dog dog = new Dog();
dog.eat(1);
复制代码

image.png

这没有什么问题,我们修改一下参数,给入参增加一个 Dog 参数 ,调用的时候依旧调用一个 int

public int eat(Dog this,int num)
复制代码

image.png 没有报错

所以 this.name 实际上时加入了的,也就是说 jdk默认会把当前实例传入到非静态方法,参数名为 this ,位置为首位

使用类名来进行方法引用


//使用类名来进行方法引用
BiFunction<Dog, Integer,Integer> eatFunction = Dog::eat;
System.out.println("还剩下"+eatFunction.apply(dog,2)+"斤");
复制代码

**构造函数来进行方法引用 **

//构造函数的方法引用
Supplier<Dog> supplier =  Dog::new;
System.out.println("创建了新对象: "+supplier.get());
复制代码

至于 Supplier 与 BiFunction 是什么 image.png

参考juejin.cn/post/699964…

我们这里对象创建成功 image.png

Supplier 是无参构造函数,我们使用一下带参数构造函数

class Dog{
    private String name = "闪电";

    public Dog(){

    }

    //带参数构造函数
    public Dog(String name){
        this.name = name;
    }
复制代码

套路就是分析上面的表,我们dog 输入是一个 String 输出是一个Dog 查表也就是Function

//带参数的构造函数的方法引用
Function<String,Dog> function2 = Dog::new;
System.out.println("创建了对象:" +function2.apply("核桃"));
复制代码
分类:
后端
标签: