![8457523345e63a8c44738be72b6e0dab.png](https://i-blog.csdnimg.cn/blog_migrate/6436d1b3460b51729a6dc04319846618.jpeg)
前言:上次分享了对Lambda表达式的理解,这次补充一下Lambda表达式的拓展使用场景。 方法引用
一,方法引用的使用场景
我们用Lambda表达式来实现匿名方法。但有些情况下,我们用Lambda表达式仅仅是调用一些已经存在的方法,除了调用动作外,没有其他任何多余的动作,在这种情况下,我们倾向于通过方法名来调用它,而Lambda表达式可以帮助我们实现这一要求,它使得Lambda在调用那些已经拥有方法名的方法的代码更简洁、更容易理解。方法引用可以理解为Lambda表达式的另外一种表现形式。
方法引用分类大致分以下几类:
语法 | 说明 | 对应的Lambda表达式 |
---|---|---|
类名::静态方法 | 静态方法引用 | (参数) -> 类名.静态方法(参数) |
类对象::类方法 | 类方法引用(其一) | () -> 类对象.类方法(参数) |
类名::类方法 | 类方法引用(其二) | (类对象,参数) ->类名.类方法(参数) |
类名::new | 构造方法引用 | (参数) -> new 类构造方法(参数) |
二,示例说明
2.1 静态方法引用
首先参考一个简单的例子。
对一个Integer列表进行排序,Integer中已经存在静态的比较方法compare(),因此可以直接调用其静态方法。
public
通过标准的两值比较结果,对于Integer列表进行排序动作,List接口的排序实现方案在JDK1.8中是采用数组工具(java.util.Arrays)的的默认排序方案,根据比较器(java.util.Comparator<E>)的返回结果,进行排序算法。
运行结果:
[
现在我们定义一个Student类,对于Student类的年龄进行比较;
定义Student类:
import
按照一般的写法,我们需要给Student类提供一个基于Comparator<T>接口的比较器
Student年龄比较器
public
然后调用Arrays.sort()方法进行排序:
public
如果仔细看Arrays.sort()方法会发现,其具体实现为:
public
其中比较器参数Comparator是一个函数式接口,所以对于学生年龄比较的代码可以改写为:
public
我们可以尝试把年龄比较的方法放在Student类中,改写Student类如下:
@Data
这时候我们的比较方法就可以改为如下:
public
以上代码中采用Lambda表达式调用了一个已经存在的静态方法,根据第一节中所讲到的知识点,关于学生年龄比较方法最终的改写方案采用静态方法引用:
public
关于静态方法引用的介绍基本如此。
2.2 类方法引用(其一)
类方法引用(其一)是调用已经存在的实例的方法,与静态方法引用不同的是类要先实例化,静态方法引用类无需实例化,直接用类名去调用。
借助定义好的Student类做对象类,使用Java的内置函数式接口Supplier<T>做接受实例对象,代码如下:
public
输出结果如下:
Lambda
2.3 类方法引用(其二)
这个方式其实是把对象也作为参数来使用,若Lambda参数列表中的第一个参数是实例方法的参数调用者,而第二个参数是实例方法的参数时,可以使用这种类方法引用。
改造Student类,提供类方法:
@Data
具体比较:
public
BiPredicate的test()方法接受两个参数,对象stu和参数age,具体实现为stu.chekAge(age)。
基于这种方式,可以调用指定对象的方法。
2.4 构造方法引用
依旧使用Java内置函数式接口来处理方法调用动作,具体代码如下:
public
需要注意的是:使用构造方法引用时,若POJO类存在多个构造方法,使用方法引用时要保证形参列表的顺序与函数式接口中抽象方法的参数列表保持一致,这样函数式接口会自动定位到对应的构造方法。
参考资料
- Java 8 新特性 | 菜鸟教程
最后:本文内容为个人技术整理,发布内容若得同好所爱,请不要吝啬您得赞同,这是对我个人最大得精神鼓励。