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. Java实现 LeetCode 496 下一个更大元素 I

    496. 下一个更大元素 I 给定两个没有重复元素的数组 nums1 和 nums2 ,其中nums1 是 nums2 的子集.找到 nums1 中每个元素在 nums2 中的下一个比其大的值. nu ...

  2. Java实现 蓝桥杯VIP 算法提高 种树

    算法提高 种树 时间限制:1.0s 内存限制:256.0MB 种树 问题描述 A城市有一个巨大的圆形广场,为了绿化环境和净化空气,市政府决定沿圆形广场外圈种一圈树.园林部门 得到指令后,初步规划出n个 ...

  3. Java实现 LeetCode 151 翻转字符串里的单词

    151. 翻转字符串里的单词 给定一个字符串,逐个翻转字符串中的每个单词. 示例 1: 输入: "the sky is blue" 输出: "blue is sky th ...

  4. Java实现 LeetCode 133 克隆图

    133. 克隆图 给你无向 连通 图中一个节点的引用,请你返回该图的 深拷贝(克隆). 图中的每个节点都包含它的值 val(int) 和其邻居的列表(list[Node]). class Node { ...

  5. Java实现 LeetCode 16 最接近的三数之和

    16. 最接近的三数之和 给定一个包括 n 个整数的数组 nums 和 一个目标值 target.找出 nums 中的三个整数,使得它们的和与 target 最接近.返回这三个数的和.假定每组输入只存 ...

  6. Java实现 蓝桥杯 算法训练 数据交换

    试题 算法训练 数据交换 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 编写一个程序,输入两个整数,分别存放在变量x和y当中,然后使用自己定义的函数swap来交换这两个变量的值. ...

  7. Java实现LeetCode_0020_ValidParentheses

    package javaLeetCode.primary; import java.util.Scanner; import java.util.Stack; public class ValidPa ...

  8. Java实现 洛谷 P1089 津津的储蓄计划

    import java.util.*; public class Main { public static void main(String[] args) { Scanner sc=new Scan ...

  9. 原生js ajax 封装

    首先我们先了解ajax的get和post请求分别是怎样请求数据的 get请求 let ajx = new XMLHttpRequest() //创建ajax实例 /*打开需要请求的地址,可以有三个参数 ...

  10. 大顶堆与小顶堆应用---寻找前k小数

    vector<int> getLeastNumber(vector<int>& arr,int k){ vector<int> vec(k,); if(== ...