这是我参与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("看看结果");
静态方法的方法引用
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);
}
}
以上输入是一个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)+"斤");
}
}
这里发现
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);
这没有什么问题,我们修改一下参数,给入参增加一个 Dog 参数 ,调用的时候依旧调用一个 int
public int eat(Dog this,int num)
没有报错
所以 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 是什么
我们这里对象创建成功
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("核桃"));