java lambda 好处_JAVA 8 新特性之 为什么要使用 Lambda 表达式?

前序 Lambda 表达式 介绍:

1:在 java 8 中引入了一个新的操作符"->",该操作符称为箭头操作符或Lambda操作符。2:箭头操作符将Lambda表达式才分为两部分。

左侧:Lambda 表达式的参数列表。

右侧:Lambda 体,即对接口的实现。

3:学习 Lambda 表达式先 应该了解一个知识点 ”函数式接口“,使用 Lambda 表达式必须要有“函数式接口”支持。

@FunctionalInterface 注解:

该注解能够强制要求接口为 ”函数式接口“

代码演示:不用 @FunctionalInterface  注解:

packagecom.test.factory;public interfaceFunctionalInterfaceTest {/*** 获取 用户姓名

*@return

*/String getName();/*** 获取用户年龄*/

voidgetage();

}

代码演示:使用@FunctionalInterface 注解: 存在了多个 抽象方法,所以指定 该注解 会报错,意思就是该接口必须指定成 “函数式接口”。

2bc1da5b2bbeb2b37e9331c937767ec1.png

若接口中存在 一个以上的抽象方法,就不能称之为 ”函数式接口", @FunctionalInterface 可以强制要求该类必须为“函数式接口”。

若要定义 “函数式接口” 只需要保存一个 抽象方法 即可。用不用 @FunctionalInterface 注解都不重要

如下图:只保留一个 抽象方法,就是一个合法的 “函数式接口”。

fffdaec8c98f49a13e1c9f68b02c8f1c.png

经典的函数式接口:Runnable

3bd98122c7022e2bb121d9799350ed27.png

学习过多线程的朋友应该很清楚这个 接口。

“函数式接口" 定义总结:

“函数式接口” 的含义:

核心:就是为了支持 Lambda 表达式 所定义的接口,

定义:“函数式接口” 必须保证 该接口 只有一个 抽象方法。

@FunctionalInterface注解:可以强制要求 该接口必须为 “函数式接口”。

Lambda 表达式 优点:

Lambda 表达式 只有一个优点:省,简化重复代码,只保留核心代码。使代码逻辑更加清晰。

Lambda 表达式 代码演示:

多说无益,看不到效果,即便说的天花烂醉又是如何?接下来统过一个 小小的案例,见识一下 Lambda 表达式 的 魅力之处。

需求:有一组员工信息存放到一个集合中,并且按照不同需求,来获取员工信息。

声明:案例展示中的案例 来源于 https://www.bilibili.com/video/av71563078?p=2 ,代码是我学习时按照视频课程内容讲解敲的(主要是想思考Lambda 的 演进过程,实际工作中用过Lambda,只是不知道是Lambda表达式,当时很傻的以为是idea 支持这么做)。

记录博客,只是单纯的记录一下学习笔记,看别人的代码还不如自己动手敲一遍,找个差不多的案例。如有侵权,请联系我,我会主动删除。

对于内容思考有所不对的地方请指明出来,一起学习,一起进步。

再次声明:以下代码只是我学习时,练手代码,对于质量我不敢保证,真正想学习 Lambda 的朋友,可以看视频教程或其他高质量的博客。

案例展示:

员工实体对象

/***@authorAdministrator

*@version1.0

* @describe 员工信息 POJO

* @date 2019/12/20 19:52*/

public classStaffModel {/*** 姓名*/

privateString name;/*** 年龄*/

private intage;/*** 性别*/

private chargender;/*** 薪资*/

private doublesalary;

get()...

set()...

toString()...

}

员工信息集:以下案例会都用这些数据。

public classLambdaTest {private static List staffModelList=new ArrayList<>();static{

staffModelList.add(new StaffModel("张三",25,'男',5000));

staffModelList.add(new StaffModel("村花",25,'女',5500));

staffModelList.add(new StaffModel("李飞飞",21,'男',2000));

staffModelList.add(new StaffModel("牛妞妞",30,'女',10000));

staffModelList.add(new StaffModel("王晓非",24,'男',6000));

}

}

传统方式:

案例一:普通的获取 工作大于或等于5000的 员工信息

/*** 需求一:获取员工中 工资大于或五千的 员工信息

*@return

*/

public static List salaryFilter(Listlist){

List staffModelList=new ArrayList<>();for (int i = 0; i < list.size(); i++) {if (list.get(i).getSalary() >= 5000) {

staffModelList.add(list.get(i));

}

}returnstaffModelList;

}/*** 测试

*@paramargs*/

public static voidmain(String[] args) {

System.out.println(salaryFilter(staffModelArrayList));

}//结果

[StaffModel{name='张三', age=25, gender=男, salary=5000.0},

StaffModel{name='村花', age=25, gender=女, salary=5500.0},

StaffModel{name='牛妞妞', age=30, gender=女, salary=10000.0},

StaffModel{name='王晓非', age=24, gender=男, salary=6000.0}]

案例二:获取 男性的员工信息

/*** 需求二:获取男性员工信息

*@return

*/

public static List genderFilter(Listlist){

List staffModelList=new ArrayList<>();for (int i = 0; i < list.size(); i++) {if (list.get(i).getGender() == '男') {

staffModelList.add(list.get(i));

}

}returnstaffModelList;

}/*** 测试

*@paramargs*/

public static voidmain(String[] args) {

System.out.println(genderFilter(staffModelArrayList));

}//测试

[StaffModel{name='张三', age=25, gender=男, salary=5000.0},

StaffModel{name='李飞飞', age=21, gender=男, salary=2000.0},

StaffModel{name='王晓非', age=24, gender=男, salary=6000.0}]

整体代码展示:

/*** 需求一:获取员工中 工资大于或五千的 员工信息

*@return

*/

public static List salaryFilter(Listlist){

List staffModelList=new ArrayList<>();for (int i = 0; i < list.size(); i++) {if (list.get(i).getSalary() >= 5000) {

staffModelList.add(list.get(i));

}

}returnstaffModelList;

}/*** 需求二:获取男性员工信息

*@return

*/

public static List genderFilter(Listlist){

List staffModelList=new ArrayList<>();for (int i = 0; i < list.size(); i++) {if (list.get(i).getGender() == '男') {

staffModelList.add(list.get(i));

}

}returnstaffModelList;

}

总结与思考

在传统方式中(如上例),面对不同的需求,我们需要 编写不同的方法(genderFilter()、genderFilter()),来实现,但是核心代码只有一句,

if (不同需求的条件(核心代码)) {

staffModelList.add(list.get(i));

}

若我们还有一个需求,获取年龄在25或25以上的员工信息,在传统方式中,我们无非就是再创建一个方法 copy 上面案例代码,更改 if(list.get(i).getAge()>=25) 这一句代码而已。

因为这一句代码,我们需要写很多重复性代码,如需求一 和 需求二,其实我们要改变的只有 if 条件判断而已。其他代码都不会做任何改动。

对于这样的代码,我们需要进行优化。只留核心,剔除其他。

优化方式一:设计模式

定义一个接口,由子类实现,完成过滤

/*** 过滤 策略 接口

*@authorAdministrator

*@param*/

public interface FilterStrategy{booleanfilter(T t);

}

创建一个子类,实现其接口,过滤规则由子类来定义

/*** 薪资过滤,

* 案例:过滤工资大于或等于 5000 的 员工

*@authorAdministrator*/

public class SalaryFilter implements FilterStrategy{

@Overridepublic booleanfilter(StaffModel staffModel) {return staffModel.getSalary()>=5000;

}

}

具体实现 案例一:普通的获取 工作大于或等于5000的 员工信息

/*** 员工过滤

*@paramlist 员工信息集

*@paramstrategy 过滤策略

*@return

*/

public static List staffFilter(List list,FilterStrategystrategy){

List staffModelList=new ArrayList<>();for (int i = 0; i < list.size(); i++) {if(strategy.filter(list.get(i))) {

staffModelList.add(list.get(i));

}

}returnstaffModelList;

}/*** 测试

*@paramargs*/

public static voidmain(String[] args) {//采用 薪资过滤策略

List staffModelList=staffFilter(staffModelArrayList,newSalaryFilter());

System.out.println(staffModelList);

}//测试结果

[StaffModel{name='张三', age=25, gender=男, salary=5000.0},

StaffModel{name='村花', age=25, gender=女, salary=5500.0},

StaffModel{name='牛妞妞', age=30, gender=女, salary=10000.0},

StaffModel{name='王晓非', age=24, gender=男, salary=6000.0}]

具体实现 案例二: 获取 男性的员工信息

/*** 案例二:获取员工中所有男性员工信息

*@authorAdministrator*/

public class GenderFilter implements FilterStrategy{

@Overridepublic booleanfilter(StaffModel staffModel) {return staffModel.getGender()=='男';

}

}/*** 测试

*@paramargs*/

public static voidmain(String[] args) {//采用 薪资过滤策略

List staffModelList=staffFilter(staffModelArrayList,newGenderFilter());

System.out.println(staffModelList);

}//运行结果

[StaffModel{name='张三', age=25, gender=男, salary=5000.0},

StaffModel{name='李飞飞', age=21, gender=男, salary=2000.0},

StaffModel{name='王晓非', age=24, gender=男, salary=6000.0}]

总结与思考:

这里采用的设计模式 为策略设计模式,与之前按照不同的需求来创建方法的传统方式相比,设计模式减少了冗余代码量,方法只有一个方法,只是需要按照不同的需求创建策略就行了。减少了冗余代码。只关注于核心。符合了OCP 原则。

案例二展示:

1:新建了一个过滤规则:性别过滤规则2:方法依旧是那个方法,只是main 方法 中的过滤规则变了。

/*** 案例二:获取员工中所有男性员工信息

*@authorAdministrator*/

public class GenderFilter implements FilterStrategy{

@Overridepublic booleanfilter(StaffModel staffModel) {return staffModel.getGender()=='男';

}

}/*** 员工过滤

*@paramlist 员工信息集

*@paramstrategy 过滤策略

*@return

*/

public static List staffFilter(List list,FilterStrategystrategy){

List staffModelList=new ArrayList<>();for (int i = 0; i < list.size(); i++) {if(strategy.filter(list.get(i))) {

staffModelList.add(list.get(i));

}

}returnstaffModelList;

}/*** 测试

*@paramargs*/

public static voidmain(String[] args) {//采用 性别过滤策略

List staffModelList=staffFilter(staffModelArrayList,newGenderFilter());

System.out.println(staffModelList);

}

优化方式二:匿名内部类

上一步方式的缺点:

上一步的优化方式是采用策略模式,那么他有什么缺点呢?设计模式肯定是没有缺点,这是再这里的案例中比较浪费,只要凡是增加一个需求,就必须创建一个类,编写相对应的过滤策略。之所以说浪费,是因为类代码少,又不得不创建一个新类(心累),显得很浪费而已。

所以这里又有一种优化方式,匿名内部类。

代码展示:

/*** 员工过滤

*@paramlist 员工信息集

*@paramstrategy 过滤策略

*@return

*/

public static List staffFilter(List list,FilterStrategystrategy){

List staffModelList=new ArrayList<>();for (int i = 0; i < list.size(); i++) {if(strategy.filter(list.get(i))) {

staffModelList.add(list.get(i));

}

}returnstaffModelList;

}/*** 测试 采用匿名内部类方式 进行过滤,过滤 年龄在 22 以上的员工信息

*@paramargs*/

public static voidmain(String[] args) {

List staffModelList = staffFilter(staffModelArrayList, new FilterStrategy() {

@Overridepublic booleanfilter(StaffModel staffModel) {return staffModel.getAge()>22;

}

});

System.out.println(staffModelList);

}//运行结果

[StaffModel{name='张三', age=25, gender=男, salary=5000.0},

StaffModel{name='村花', age=25, gender=女, salary=5500.0},

StaffModel{name='牛妞妞', age=30, gender=女, salary=10000.0},

StaffModel{name='王晓非', age=24, gender=男, salary=6000.0}]

总结与思考

对于上一种优化方式,不必再创建一个新的过滤器类。相对较而言,代码更少,更清晰。

优化方式三:Lambda 表达式

如果你的是 Idea 你会发现当你写 匿名内部类的时候,他已经提示你可以进行优化了

c4997cda45bcf41cbc986c0f881a7c83.png

优化后的效果:代码已经缩短成了 两句代码 标志为 橙色 的就是我们需要的核心代码。

/*** 测试

*@paramargs*/

public static voidmain(String[] args) {

List staffModelList = staffFilter(staffModelArrayList, staffModel -> staffModel.getAge()>22);

System.out.println(staffModelList);

}//运行结果

[StaffModel{name='张三', age=25, gender=男, salary=5000.0},

StaffModel{name='村花', age=25, gender=女, salary=5500.0},

StaffModel{name='牛妞妞', age=30, gender=女, salary=10000.0},

StaffModel{name='王晓非', age=24, gender=男, salary=6000.0}]

再来一个需求,获取名称为 “张三” 的员工信息

/*** 测试

*@paramargs*/

public static voidmain(String[] args) {

List staffModelList = staffFilter(staffModelArrayList, staffModel -> staffModel.getName().equals("张三"));

System.out.println(staffModelList);

}//运行结果

[StaffModel{name='张三', age=25, gender=男, salary=5000.0}]

总结与思考

Lambda 表达式 优化了我们代码,使我们的代码看起来,更加简单和清晰。Lambda 表达式 的支持,需要 jdk1.8 以上(听说 jdk 已经 都11了)而我实际工作中用的还是 jdk8,对jdk 8的特性了解甚少。惭愧

优化方式四:Steam ApI

应该是 jdk8 新的特性,不是很了解,直接代码展示吧

public classLambdaTest {private static List staffModelArrayList=new ArrayList<>();static{

staffModelArrayList.add(new StaffModel("张三",25,'男',5000));

staffModelArrayList.add(new StaffModel("村花",25,'女',5500));

staffModelArrayList.add(new StaffModel("李飞飞",21,'男',2000));

staffModelArrayList.add(new StaffModel("牛妞妞",30,'女',10000));

staffModelArrayList.add(new StaffModel("王晓非",24,'男',6000));

}/*** 测试

*@paramargs*/

public static voidmain(String[] args) {

staffModelArrayList

.stream()

.filter((e)-> e.getAge()>22) //过滤 年龄 大于 22 的员工信息

.forEach(System.out::println); // 进行打印 类似 System.out.println

}

}//运行结果

StaffModel{name='张三', age=25, gender=男, salary=5000.0}

StaffModel{name='村花', age=25, gender=女, salary=5500.0}

StaffModel{name='牛妞妞', age=30, gender=女, salary=10000.0}

StaffModel{name='王晓非', age=24, gender=男, salary=6000.0}

除此之外还可以进行 向 sql 那样 分页(limit)

/*** 测试

*@paramargs*/

public static voidmain(String[] args) {

staffModelArrayList

.stream()

.filter((e)-> e.getAge()>22)//获取前两条数据

.limit(2)

.forEach(System.out::println);

}//运行结果

StaffModel{name='张三', age=25, gender=男, salary=5000.0}

StaffModel{name='村花', age=25, gender=女, salary=5500.0}

总结与思考

除此之外,还有hash 等,都有很好的优化处理。只能感叹,更新太快,工作太忙,太多东西学不完。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值