JDK8--02:为什么要使用lambda
lambda是一个匿名函数,我们可以把lambda理解为一个可以传递的代码(将代码像数据一样传递),可以写出更简洁更灵活的代码。
首先看一下原来的匿名内部类实现方式(以比较器为例)
//原来的匿名内部类实现方式
public void test1(){
//定义一个匿名内部类comparator
Comparator<Integer> comparator = new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return Integer.compare(o1,o2);
}
};
//将匿名内部类作为对象传入
TreeSet<Integer> treeSet = new TreeSet<>(comparator);
}
以上代码实际上实际有用的代码只有两行(第7行),但是却需要写这么多代码,非常痛苦,lambda就很好的解决了该问题。
lambda实现方式
//lambda表达式实现
public void test2(){
//lambda表达式
Comparator<Integer> comparator = (x,y)->Integer.compare(x,y);
//将匿名内部类作为对象传入
TreeSet<Integer> treeSet = new TreeSet<>(comparator);
}
通过以上可以看到,原来的多行代码,变为了一行实现,代码量大大减少,但是,如果只是这样的一个结论,显然不能说服人(匿名内部类我直接就可以一键生成,对开发来说影响并不是很大,反而要学习一个新的语法,这种投入产出比不太大)
所以再举一个例子来说明lambda的优势:
需求1:获取公司中年龄大于35岁的员工
先创建实体类
package com.example.jdk8demo.lambda; import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.ToString; @Data
@RequiredArgsConstructor
@AllArgsConstructor
@ToString
public class Employer {
private String name;
private Integer age;
private double salary;
}
为了方便演示,就不再进行数据库操作,直接模拟一个员工集合
/**
* 模拟员工集合
*/
private List<Employer> list = Arrays.asList(
new Employer("张三",,2222.22),
new Employer("李四",,3333.33),
new Employer("王五",,4444.44),
new Employer("赵六",,5555.55),
new Employer("田七",,4235.32),
new Employer("牛八",,3256.52)
);
然后就是实现逻辑代码,我们一般会直接定义一个方法去实现,如下代码所示
/**
* 查询年龄大于35岁的员工
* @return
*/
public List<Employer> getEmpolyerByAge(){
List<Employer> employerList = new ArrayList<>();
for (Employer employer : list){
if(employer.getAge() > ){
employerList.add(employer);
}
}
return employerList;
}
那么如果此时,又来了一个需求
需求2:查询工资大于4000的员工
我们还需要再写一个实现方法
/**
* 查询工资大于4000的员工
* @return
*/
public List<Employer> getEmpolyerBySalary(){
List<Employer> employerList = new ArrayList<>();
for (Employer employer : list){
if(employer.getSalary() > ){
employerList.add(employer);
}
}
return employerList;
}
可以发现,两个方法中,只有 employer.getAge() > 35 和 employer.getSalary() > 4000 是不同的,其余的代码都一样,如果后续还有新的类似需求增加,呢么冗余代码会越来越多,因此我们就需要对代码进行优化。
优化方案一:使用策略模式
一般情况下,对于这种冗余代码,我们的优化会使用策略模式进行优化
首先,先创建一个接口
package com.example.jdk8demo.lambda;
public interface EmpolyerService<T> {
boolean filter(T t);
}
然后针对不同的需求,做不同的实现类
第一个实现类是针对查询年龄大于35的员工
package com.example.jdk8demo.lambda;
public class EmpolyerImplByage implements EmpolyerService<Employer> {
@Override
public boolean filter(Employer employer) {
return employer.getAge() > ;
}
}
第二个实现类是针对查询公司大于4000的员工
package com.example.jdk8demo.lambda;
public class EmpolyerImplBySalary implements EmpolyerService<Employer> {
@Override
public boolean filter(Employer employer) {
return employer.getSalary() > ;
}
}
然后就是使用策略模式进行查询,方法的入参是接口的实现类,然后根据实现类中对接口方法的不同实现进行不同的处理。
/**
* 使用策略模式查询员工信息
* @param empolyerService
* @return
*/
public List<Employer> getEmpolyerList(EmpolyerService<Employer> empolyerService){
List<Employer> employerList = new ArrayList<>();
for (Employer employer : list){
if(empolyerService.filter(employer)){
employerList.add(employer);
}
}
return employerList;
}
最后所有需求都统一调用新增的策略模式方法,具体的入参就是接口具体的实现类
/**
* 优化一:采用策略模式
*/
public void test5(){
List<Employer> employerList = getEmpolyerList(new EmpolyerImplByage());
for (Employer employer : employerList){
log.info(employer.toString());
}
log.info("=============================================");
employerList = getEmpolyerList(new EmpolyerImplBySalary());
for (Employer employer : employerList){
log.info(employer.toString());
}
}
这种优化也有不好的地方,就是一个需求就要创建一个实现类,随着需求的增加,实现类会越来越多,所以可以进一步进行优化
优化方案二:使用匿名内部类
由于采用策略模式,一个需求就需要创建一个实现类,导致文件增多,因此可以将策略模式改为使用匿名内部类,使用匿名内部类,仍然需要上述的过滤接口,但是无需再使用接口的实现类
/**
* 优化方式二:匿名内部类
*/
public void test6(){
List<Employer> employerList = getEmpolyerList(new EmpolyerService<Employer>() {
@Override
public boolean filter(Employer employer) {
return employer.getAge() > ;
}
});
for (Employer employer : employerList){
log.info(employer.toString());
}
log.info("=============================================");
employerList = getEmpolyerList(new EmpolyerService<Employer>() {
@Override
public boolean filter(Employer employer) {
return employer.getSalary() > ;
}
});
for (Employer employer : employerList){
log.info(employer.toString());
}
}
由此已经对应了本文刚开始的时候,匿名内部类中有用的代码实际就一行,但是缺需要写大量其他无用的代码,因此可以使用lambda进行优化。
优化方案三:使用lambda
/**
* 优化方式七:lambda表达式
*/
public void test7(){
LambdaTest lambdaTest = new LambdaTest();
List<Employer> employerList = lambdaTest.getEmpolyerList((e) -> e.getAge()>);
employerList.forEach(System.out::println);
log.info("=============================================");
employerList = lambdaTest.getEmpolyerList((e)->e.getSalary()>);
employerList.forEach(System.out::println);
}
可以发现,使用lambda表达式后,代码简单、简洁。到此处,为什么要使用lambda已经描述完毕,但是对于java8来说,还有更简洁的优化方式,就是Stream流。
优化方式四:Stream流
此种实现,不需要像前三种优化方式一样新建接口,这里直接使用流式过滤即可。
/**
* 使用StreamAPI查询员工信息
*/
public void test8(){
list.stream()//流式处理
.filter((e)->e.getSalary()>)//过滤出工资大于2000的员工
.filter((e)->e.getAge()>)//过滤出年龄大于30的员工
.limit()//只查询前两条
.forEach(System.out::println);//循环打印
}
JDK8--02:为什么要使用lambda的更多相关文章
- 02、Java的lambda表达式和JavaScript的箭头函数
前言 在JDK8和ES6的语言发展中,在Java的lambda表达式和JavaScript的箭头函数这两者有着千丝万缕的联系:本次试图通过这篇文章弄懂上面的两个"语法糖". 简介 ...
- Jdk8的学习之lambda
在JDK8中,引入了Lambda(读:了母达)表达式的概念,这是我最喜欢的特性,很多东西都变得简单了,一行代码可以搞定. 比如说排序 /** * 这是一个JDK8的lambda的排序应用 */ pub ...
- JDK8新特性之一Lambda
JDK8的新特性之一Lambda能将函数作为方法里面的参数使用. /** * JDK8新特性Lambda */ public class Test { public static void main( ...
- JDK15就要来了,你却还不知道JDK8的新特性!
微信搜「烟雨星空」,白嫖更多好文. 现在 Oracle 官方每隔半年就会出一个 JDK 新版本.按时间来算的话,这个月就要出 JDK15 了.然而,大部分公司还是在使用 JDK7 和 8 . 之前去我 ...
- JDK8.0新特性
连接转载地址:http://www.2cto.com/kf/201609/544044.html Eclipse: http://aiyiupload.oss-cn-beijing.aliyuncs. ...
- JDK8到JDK12各个版本的重要特性整理
JDK8新特性 1.Lambda表达式 2.函数式编程 3.接口可以添加默认方法和静态方法,也就是定义不需要实现类实现的方法 4.方法引用 5.重复注解,同一个注解可以使用多次 6.引入Optiona ...
- SpringCloudGateWay学习 之 从函数式编程到lambda
文章目录 前言: 函数式编程: 什么是函数式编程: 函数式编程的特点 lambda表达式: 核心: 函数接口: 方法引用: 类型推断: 变量引用: 级联表达式跟柯里化: 前言: 这一系列的文章主要是为 ...
- 看看 JDK 8 给我们带来什么(转)
世界正在缓慢而稳步的改变.这次改变给我们带来了一个新模样的JDK7,java社区也在一直期盼着在JDK8,也许是JDK9中出现一些其他的改进.JDK8的改进目标是填补JDK7实现中的一些空白——部分计 ...
- Django框架
一.首先,到底什么是框架? 想要回答这个问题,我们要慢慢来. ①首先从DRY原则开始说起 Don't Repeat Yourself,不要重复你的代码. DRY原则的重要性怎么提都不过分,很多人说编程 ...
- JAVA开发第一步——JDK 安装
JDK,Java Development Kit. And JRE ,Java Runtime Environment. jdk分64位和32位,可自行去Oracle官网下载 直接百度下载链接 Win ...
随机推荐
- jQuery-DOM增删查改
1.绑定事件 $().事件名(function(){功能}) 事件名:鼠标事件 键盘事件 表单事件 事件委托:$().on('事件名',#####'target',function(){功能}) 额外 ...
- Java实现 LeetCode 738 单调递增的数字(暴力)
738. 单调递增的数字 给定一个非负整数 N,找出小于或等于 N 的最大的整数,同时这个整数需要满足其各个位数上的数字是单调递增. (当且仅当每个相邻位数上的数字 x 和 y 满足 x <= ...
- Java实现构造无向图的欧拉回路( The Necklace)
中文翻译: 但是,唉!一天,项链被撕破了,珠子散落在屋檐上.我姐姐尽力把地板上的珠子都捡起来了.但她不确定自己是否能收集到所有的照片.现在,她来找我帮忙.她想知道是否有可能让克劳斯使用她在里面的所有珠 ...
- Python学习之输入输出入门 A+B篇
描述 求两个整数之和. 输入 输入数据只包括两个整数A和B. 输出 两个整数的和. 样例输入 1 2 样例输出 3 a=input().split() print(int(a[0])+int(a[1 ...
- Mac下如何连接linux服务器(SSH)-比较好用的SSH工具推荐
Mac下如何连接linux服务器(SSH) 1.用mac自带终端连接 步骤如下: 打开终端,在顶部shell菜单中选择新建远程连接 在右侧服务器窗口点击+号,添加服务器,输入IP等信息 输入用户名,点 ...
- 一、kafka 介绍 && kafka-client
一.kafka 介绍 1.1.kafka 介绍 Kafka 是一个分布式消息引擎与流处理平台,经常用做企业的消息总线.实时数据管道,有的还把它当做存储系统来使用. 早期 Kafka 的定位是一个高吞吐 ...
- 使用Java将阿拉伯数字转换为中文数字(适配小数转换)
Java数字转换工具类 简介 该工具类可以将整数.小数.负数转换为中文的数字,如: 0 --> 零 1 --> 一 2.1 --> 二点一 -2.1 --> 负二点一 具体代码 ...
- 温故知新-多线程-forkjoin、CountDownLatch、CyclicBarrier、Semaphore用法
Posted by 微博@Yangsc_o 原创文章,版权声明:自由转载-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 3.0 文章目录 摘要 forkjoin C ...
- iOS-地图定位 && 解码与反解码
前段时间,公司开发的App用到了地图和定位,所以记录一下,作为回顾总结. 对于地图和定位,苹果公司提供给了两个框架: MapKit:用于地图展示 Core Location ...
- 嵌入式Linux内核开发工程师必须掌握的三十道题
如果你能正确回答以下问题并理解相关知识点原理,那么你就可以算得上是基本合格的Linux内核开发工程师. 1. Linux中主要有哪几种内核锁?(进程同步与互斥) (1)自旋锁:非睡眠锁 (2)信号量: ...