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的更多相关文章

  1. 02、Java的lambda表达式和JavaScript的箭头函数

    前言 在JDK8和ES6的语言发展中,在Java的lambda表达式和JavaScript的箭头函数这两者有着千丝万缕的联系:本次试图通过这篇文章弄懂上面的两个"语法糖". 简介 ...

  2. Jdk8的学习之lambda

    在JDK8中,引入了Lambda(读:了母达)表达式的概念,这是我最喜欢的特性,很多东西都变得简单了,一行代码可以搞定. 比如说排序 /** * 这是一个JDK8的lambda的排序应用 */ pub ...

  3. JDK8新特性之一Lambda

    JDK8的新特性之一Lambda能将函数作为方法里面的参数使用. /** * JDK8新特性Lambda */ public class Test { public static void main( ...

  4. JDK15就要来了,你却还不知道JDK8的新特性!

    微信搜「烟雨星空」,白嫖更多好文. 现在 Oracle 官方每隔半年就会出一个 JDK 新版本.按时间来算的话,这个月就要出 JDK15 了.然而,大部分公司还是在使用 JDK7 和 8 . 之前去我 ...

  5. JDK8.0新特性

    连接转载地址:http://www.2cto.com/kf/201609/544044.html Eclipse: http://aiyiupload.oss-cn-beijing.aliyuncs. ...

  6. JDK8到JDK12各个版本的重要特性整理

    JDK8新特性 1.Lambda表达式 2.函数式编程 3.接口可以添加默认方法和静态方法,也就是定义不需要实现类实现的方法 4.方法引用 5.重复注解,同一个注解可以使用多次 6.引入Optiona ...

  7. SpringCloudGateWay学习 之 从函数式编程到lambda

    文章目录 前言: 函数式编程: 什么是函数式编程: 函数式编程的特点 lambda表达式: 核心: 函数接口: 方法引用: 类型推断: 变量引用: 级联表达式跟柯里化: 前言: 这一系列的文章主要是为 ...

  8. 看看 JDK 8 给我们带来什么(转)

    世界正在缓慢而稳步的改变.这次改变给我们带来了一个新模样的JDK7,java社区也在一直期盼着在JDK8,也许是JDK9中出现一些其他的改进.JDK8的改进目标是填补JDK7实现中的一些空白——部分计 ...

  9. Django框架

    一.首先,到底什么是框架? 想要回答这个问题,我们要慢慢来. ①首先从DRY原则开始说起 Don't Repeat Yourself,不要重复你的代码. DRY原则的重要性怎么提都不过分,很多人说编程 ...

  10. JAVA开发第一步——JDK 安装

    JDK,Java Development Kit. And JRE ,Java Runtime Environment. jdk分64位和32位,可自行去Oracle官网下载 直接百度下载链接 Win ...

随机推荐

  1. Rocket - config - Parameters

    https://mp.weixin.qq.com/s/uLEr9gAFaMDIXa8S9xJVTw   介绍配置类Parameters及其伴生对象的实现.   参考链接: https://docs.q ...

  2. 基于GTID搭建主从MySQL

    目录 基于gtid搭建主从MySQL 一.GTID的使用 二.GTID的简介 三.GTID的构成 四.查看GTID的执行情况 4.1 gtid_executed 4.2 gtid_own 4.3 gt ...

  3. Java实现 LeetCode 731 我的日程安排表 II(二叉树)

    731. 我的日程安排表 II 实现一个 MyCalendar 类来存放你的日程安排.如果要添加的时间内不会导致三重预订时,则可以存储这个新的日程安排. MyCalendar 有一个 book(int ...

  4. Java实现 LeetCode 433 最小基因变化

    433. 一条基因序列由一个带有8个字符的字符串表示,其中每个字符都属于 "A", "C", "G", "T"中的任意一 ...

  5. Java实现 LeetCode 352 将数据流变为多个不相交区间

    352. 将数据流变为多个不相交区间 给定一个非负整数的数据流输入 a1,a2,-,an,-,将到目前为止看到的数字总结为不相交的区间列表. 例如,假设数据流中的整数为 1,3,7,2,6,-,每次的 ...

  6. Java实现 蓝桥杯VIP 算法提高 贪吃的大嘴

    算法提高 贪吃的大嘴 时间限制:1.0s 内存限制:256.0MB 问题描述 有一只特别贪吃的大嘴,她很喜欢吃一种小蛋糕,而每一个小蛋糕有一个美味度,而大嘴是很傲娇的,一定要吃美味度和刚好为m的小蛋糕 ...

  7. Arrays.binarySearch和Collections.binarySearch的详细用法

    概述 binarysearch为在指定数组中查找指定值得索引值,该值在范围内找得到则返回该值的索引值,找不到则返回该值的插入位置,如果该值大于指定范围最大值则返回-(maxlength+1),而: i ...

  8. webpack从单页面到多页面

    前言 从上次更完webpack从什么都不懂到入门之后,好久没有更新过文章了,可能是因为自己懒了吧.今天看了下自己的索引量少了一半o(╥﹏╥)o,发现事态严重,赶紧更新一篇23333 也是因为最近踩了一 ...

  9. 如何0基础学习C/C++?

    谈及C/C++,功能强大.应用广泛,一旦掌握了后,若是再自学其他语言就显得轻而易举了.那为什么学C/C++的人少呢?很多人认为C/C++虽然博大精深,但也难学.其实就本人认为C/C++并非是“diff ...

  10. Flutter upgrade更新版本引发的无法启动调试APP的错误 target:kernel_snapshot failed”

    前言 我的主机上的Flutter 本地的分支是在 beta,因为去年想尝鲜Flutter Web,所以一直没切回来stable分支. 早上打开VSCode,右下角弹出了Flutter upgrade的 ...