本文共 3492 字,大约阅读时间需要 11 分钟。
在学习lambda
之前先来看一段代码,传入一个User的集合,返回符合条件的User集合
public static Listfilter(List users, Predicate predicate) { List result = new ArrayList<>(); for (User user: users){ if (predicate.test(user)) result.add(user); } return result; }
代码中使用了Predicate
接口, 接受一个泛型T,返回一个布尔值
@FunctionalInterface public interface Predicate{ boolean test(T t); }
java7中,我们可以使用匿名内部类
来作为入参来调用filter
方法
public static ListfilterZhang(List users) { return filter(users, new Predicate () { @Override public boolean test(User user) { return user.getName().startsWith("张"); } }); }
java8中,我们可以使用lambda
来实现
public static ListfilterWang(List users) { return filter(users, user -> user.getName().startsWith("王")); }
lambda其实是一个箭头函数
,也可称为匿名函数
,类似于ES6
中的箭头函数,只不过javascript
中使用=>
, 而java中使用->
箭头操作符将lambda表达式分成了两部分:
抽象方法
的参数列表)抽象方法
的实现)上面说到的抽象方法,指的就是Predicate接口中唯一的一个抽象方法 test,接收一个泛型T,返回boolean值
boolean test(T t)
再看看我们写的lambda表达式, 是不是接受一个泛型为User的user对象,如果user的姓王就返回true,反之返回false, 参数和返回值 一一对应
user -> user.getName().startsWith("王")
所以 lambda箭头函数必须和Predicate
接口中那个唯一
的抽象方法保持一致(参数和返回值完全相同),正因为如此,lambda中会对参数类型进行类型推断
, 我们只写了一个user, java就知道这是一个User对象
语法有如下几种格式:
() -> 具体实现
(x) -> 具体实现 //或 x -> 具体实现
(x,y) -> { 具体实现}
注:lambda表达式的参数列表的参数类型可以省略不写,可以进行类型推断
。
函数式接口大部分定义在 java.util.function
包中, 且用@FunctionalInterface
注解
需求:需要对两个数进行加减乘除等运算,怎么实现?
public static void main(String[] args) { add(2,1); minus(2,1); multiply(2,1); divide(2,1); } static int add(int left, int right) { return left + right; } static int minus(int left, int right) { return left - right; } static int multiply(int left, int right) { return left * right; } static int divide(int left, int right) { return left / right; }
lambda做法:首先要定义一个函数式接口,接口中只有一个方法,接收两个参数。
public static void main(String[] args) { calc(2, 1, (left, right) -> left + right); calc(2, 1, (left, right) -> left - right); calc(2, 1, (left, right) -> left * right); calc(2, 1, (left, right) -> left / right); } static int calc(int left, int right, Calculate calculate) { return calculate.applyAsInt(left, right); } @FunctionalInterface interface Calculate { int applyAsInt(int left, int right); }d
所以用lambda的话,只需要定义一个函数式接口,不管进行什么操作,都可以用lambda解决,不用再一种运算对应一个方法。但是,还需要自己定义函数式接口,好像也没简单很多。Java考虑到这点了,所以内置了函数式接口, 大部分放在java.util.function
包中, 接口用@FunctionalInterface
注解。
如Predicate接口
在将lambda时举的例子,可以换成方法引用
的写法
public static ListfilterLi(List users) { return filter(users, Demo1::test); } // test 相当于 Predicat接口中抽象方法test的实现 private static boolean test(User user) { return user.getName().startsWith("李"); }
(想自学习编程的小伙伴请搜索,更多行业相关资讯更有行业相关免费视频教程。完全免费哦!)
转载地址:http://blbp.baihongyu.com/