Lambda表达式的来龙去脉,全在这篇文章里了

news2024/12/23 20:37:54

一. 前言部分

大家都知道Lambda表达式作为JAVA 8中提供的新特性之一,在现在的企业开发中已经非常的流行了。今天壹哥就通过一个具体的案例,来带大家一起详细地探究一下Lambda表达式是如何被提出来的,以及它的出现主要是用来解决什么问题的。相信通过本文内容的讲解,各位小伙伴一定会对Lambda有一个更深入全面的认识,让我们一起开始吧。

二. 案例说明

1. 定义一个学生类

我们先来定义一个学生类。

package com.qf.day12.demo02;

public class Student {
    private String sno;
    private String name;
    private int age;
    private double score;
    public String getSno() {
        return sno;
    }
    public void setSno(String sno) {
        this.sno = sno;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public double getScore() {
        return score;
    }
    public void setScore(double score) {
        this.score = score;
    }
    public Student(String sno, String name, int age, double score) {
        super();
        this.sno = sno;
        this.name = name;
        this.age = age;
        this.score = score;
    }
    public Student() {
        super();
    }
    public void showInfo() {
        System.out.println("学号:"+  this.sno +",姓名:" +  this.name + ",年龄:" +  age + ",成绩:"+ this.score);
    }
}

2. 创建学生数组

在main方法中创建一个学生对象数组。

public static void main(String[] args) {
    //创建一个学生对象数组
    Student[] students = new Student[] {
        new Student("101","张三",23,89.5),
        new Student("102","李四",28,79.5),
        new Student("103","王五",20,90.5),
        new Student("104","赵六",26,34.5),
        new Student("105","田七",19,67.5),
        new Student("106","孙八",22,56.5)             
    };
}

下面我们来看一个需求:定义一个方法,能够根据用户提供的不同条件从整个数组中进行指学生信息的检索并输出检索的结果,这其实就是开发中非常普遍的信息查询功能。

三. 解决过程

了解到上述需求后,下面我们再来看壹哥对这个检索方法的设计。

1. 定义接口

首先我们来定义一个接口,并在接口中定义一个能够对学生对象按照一定条件进行判断的抽象方法,具体的判断规则和逻辑交由实现类去实现:

public interface Judgeable {
    //制定统一的判断方法规范
    boolean judge(Student s);
}

2. 编写实现类

接着编写接口的第一个实现类,具体的实现逻辑是判断学生成绩是否及格:

public class JudgeByScore implements Judgeable{
    @Override
    public boolean judge(Student s) {
        if(s.getScore()>=60) {
            return true;
        }
        return false;
    }
}

3. 实现信息检索

定义按给定条件进行学生信息检索的方法:

public static void filter(Student[] students,Judgeable judgeable) {
    for (int i = 0; i < students.length; i++) {
        if(judgeable.judge(students[i])) {
            students[i].showInfo();
        }
    }
}

4. 进行信息过滤

在main方法中调用filter方法进行及格的学生信息过滤:

filter(students, new JudgeByScore());

虽然需求是得到了解决,但我们也不难发现这种方式存在的问题:JudgeByScore这个类只能按照成绩进行过滤,那如果我们希望按照年龄进行过滤呢?这时我们又得编写一个接口的实现类,这样随着筛选条件的不断增多例如按照学号过滤、按照姓名过滤、过滤出90分以上的等等,我们就需要在项目中不断的编写实现类,这样就造成了类的泛滥,这又该如何解决呢?

此时我们可以想到使用JAVA中的匿名内部类对象语法进行上述过程的优化,具体的代码如下:

filter(students, new Judgeable() {          
    @Override
    public boolean judge(Student s) {
        return s.getScore()>=60;
    }
});

匿名内部类属于局部内部类的一种特殊情况,它其实就是将某个接口的实现类的定义和该实现类对象的创建合二为一,同时在这个过程中隐藏了实现类的名字。这样做的好处无疑是简化了我们的编码,在项目的目录中也没有产生新的类文件从而解决了类的泛滥问题。估计到这里,小伙伴们都没有什么问题。但是上述代码还能不能继续简化呢?答案是肯定的,我们今天的探讨的主角Lambda表达式正式登场...

5. Lambda简化操作

小伙伴们会发现上面的filter过滤方法调用的第二个参数过于繁琐,整个匿名内部类对象创建过程中很多的部分都是可以结合程序上下文进行推断出来的,并没有必要体现在代码中。例如:new 后面接口类型可以通过filter方法的第二个形参类型来推断,包括实现的方法声明部分public boolean judge(Student s)按照方法实现的要求必须和接口中定义的规范保持一致,所以这块也可以省略不写,所以我们可以将传递的第二个参数【匿名内部类对象】通过Lambda表达式的语法规则进行进一步的简化:

filter(students,(s)->{ return s.getScore()>=60; } );

以->为分割,左侧表示方法的形参列表,右侧表示方法体或方法的实现,由此我们可以认为Lambda表达式其实就是按照一定的规则对匿名内部类对象的语法简化。它最终描述的是一个实现了指定接口的方法,并且要求Lambda所描述的方法的形参列表以及返回的结果类型必须完全符合接口规范,因此我们在编写Lambda表达式的过程中脑子里想的是对应接口中方法规范。这时可能会有小伙伴问:如果接口中定义了多个抽象方法呢,我们在基于这样的接口编写Lambda表达式到底参考哪个呢?

注意了:Lambda表达式的编写是有条件的,并不是任何接口的匿名内部类对象都可以使用Lambda来简化,我们要求这个接口中只能定义一个必须被实现类强制实现的方法。也就是我们JAVA中所说的函数式接口,可以通过专门的注解@FunctionalInterface进行是否为函数式接口的标识。

根据Lambda的规则要求:

1. 如果形参只有一个的话参数的小括号可以省略不写;

2. 如果Lambda体中只要一条return语句则return关键字、Lambda的大括号以及语句的结束符分号均可同时省略。

我们还可以对上面的调用过程做进一步的简化,让整个代码看起来更加的紧凑:

filter(students,s->s.getScore()>=60);

感觉这就像是将一段代码作为方法的参数进行传递一样。

四. 内容总结

以上就是如何通过Lambda表达式,一步步精简匿名内部类对象的完整过程。正如有的小伙伴所理解的,因为JAVA 8之前对匿名内部类对象的编写语法太繁琐,所以才有了JAVA 8之后提出的Lambda表达式,用来进行语法简化提升开发效率的。通过近期毕业的学员反馈回来的信息,Lambda表达式目前在企业开发中已经非常流行了。作为个人。你可以选择不去使用它,但是作为一个团队大家都在使用的话,你作为团队的一份子如果不会,是不是很难和团队成员进行配合,是不是很容易被其他人认为你已经OUT了呢?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/126869.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

乌班图(Ubuntu)单系统或者乌班图+Win双系统安装教程

单ubuntu系统安装 1、将ubuntu系统U盘插入电脑USB接口&#xff0c;建议优先插USB3.0蓝色(彩色)接口&#xff0c;这样可以保证安装过程中文件的读取速度&#xff0c;加快安装进程。 2、然后电脑关机状态下&#xff0c;开机。开机后快速按主机的快捷启动键&#xff1a; 3、在出现…

Qt编写雷达模拟仿真工具1-背景布局

一、前言 雷达模拟仿真工具&#xff0c;整体结构采用的QGraphicsView框架&#xff0c;背景布局采用的分层绘制&#xff0c;这样可以控制该需要重新绘制的重新绘制&#xff0c;不需要重新的绘制的就没必要再多余的浪费&#xff0c;这里定义了一个GraphicsBackGroundItem类继承自…

Spring框架(容器)--简介(实现原理、核心模块、组成部分)

spring框架&#xff08;容器&#xff09; spring简介 1、Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言&#xff0c;任何Java应用都可以从Spring中受益。 2、Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。 3、轻量——从大小…

Creo9.0 Windows 3D建模工具

前言 creo9.0正式版是一款非常优秀的3D建模设计软件。该软件界面美观&#xff0c;提供了CAD 技术、模制造绘图、多实体建模、多体设计、实时仿真、框架和焊缝设计等一系列强大的辅助设计功能&#xff0c;通过这些功能&#xff0c;让用户轻松解决设计中带来的各种问题。 下载 …

律所管理系统的功能以及作用分别有哪些?

在全球进入信息化的时代&#xff0c;随着网络的普及与发展&#xff0c;网络所带来的信息交流与利用的优势愈发明显。尤其是随着法律制度的不断健全和人民法律意识的提高&#xff0c;涉及法律诉讼的案件也在不断地增加&#xff0c;律师事务所作为中介的法律机构&#xff0c;要处…

字符设备驱动(一)

1.Linux设备分类 linux的文件种类&#xff1a; -&#xff1a;普通文件 文件内容文件名元信息&#xff08;文件的相关属性—组织在inode的一个结构体内&#xff09; d&#xff1a;目录文件 p&#xff1a;管道文件 s&#xff1a;本地socket文件 l&#xff1a;链接文件 软链接&am…

4 内部类实例

内部类 内部类的分类&#xff1a; 成员内部类方法内部类局部内部类匿名类静态内部类 1 成员内部类 是在一个类中声明的类&#xff0c;包含内部类的是外围类 成员内部类的访问权限&#xff1a; public可以在外围类的外部使用内部类创建对象private只能在外围类的内部使用内…

提升Mac使用性能的5大方法,都非常的好用哦~

是不是发现你的 Mac 越用运行速度会越慢&#xff1f;没错&#xff0c;任何电子设备&#xff0c;随着使用时间的增加&#xff0c;都会出现不如刚买时那么流畅的问题。Mac当然也不能例外&#xff0c;它的运行速度会随着使用时长的递增而有所下降&#xff0c;所以为 Mac 提速也是十…

CSS总结(网页布局:标准流 浮动 定位)

CSS 主要的功能是布局页面&#xff0c;增加标签的样式和部分交互效果。 资料来源&#xff1a;黑马 目录 元素显示 块级元素 行内元素 行内块元素 显示模式的转换 CSS三个特点 盒子模型 传统三种布局 标准流 浮动 结合浮动和标准流可以搭建出常见的网页布局: 清除…

Java Integer.toBinaryString() 方法源码及原理解析(进制转换、位运算)

title: Java Integer.toBinaryString() 方法源码及原理解析&#xff08;进制转换、位运算&#xff09; date: 2022-12-27 17:31:38 tags: Java categories:Java cover: https://cover.png feature: false 1. 使用及源码概览 Integer.toBinaryString() 方法用于将十进制整数转…

【1 - 决策树 - 案例部分:泰坦尼克号幸存者预测】菜菜sklearn机器学习

课程地址&#xff1a;《菜菜的机器学习sklearn课堂》_哔哩哔哩_bilibili 第一期&#xff1a;sklearn入门 & 决策树在sklearn中的实现第二期&#xff1a;随机森林在sklearn中的实现第三期&#xff1a;sklearn中的数据预处理和特征工程第四期&#xff1a;sklearn中的降维算法…

Spring RCE漏洞CVE-2022-22965复现与JavaFx GUI图形化漏洞利用工具开发

文章目录前言一、漏洞描述二、影响范围三、漏洞复现3.1 漏洞poc四、修复建议五、图形化工具开发-Rexbb简介与使用5.1 工具使用总结前言 换了新工作&#xff0c;年底了比较多自学的时间&#xff0c;所以把今年比较经典的漏洞给复现一下&#xff0c;之前因为没空&#xff0c;只复…

python--PyCHarm里代码整体向左/右缩进

1、PyCharm 里代码整体向左缩进 鼠标选中多行代码&#xff0c;同时按住 Shift Tab 键&#xff0c;实现一次向左缩进4个字符。 2、PyCharm 里代码整体向右缩进 鼠标选中多行代码&#xff0c;按下 Tab 键&#xff0c;实现一次向右缩进4个字符。 3、PyCharm 里光标变粗 光标…

信创大提速,企业如何在高速行驶中更换“发动机”?

导读&#xff1a;信创替代如何平滑迁移不“翻车”&#xff1f; 经过多年发展&#xff0c;中国信创产业迎来全面提速。 2022年国家下发的79号文中&#xff0c;全面给出了国资信创产业发展与进度的指导&#xff0c;要求到2027年央企国企100%完成信创替代&#xff0c;替换范围涵盖…

SprintBoot实战(十一)集成 xxl-job

目录1.简介2.Maven依赖3.初始化数据库4.调度中心配置5.执行器配置6.项目结构7.访问页面8.新建定时任务9.BEAN运行模式10.GLUE(Java)运行模式1.简介 xxl-job&#xff1a; 是一个分布式任务调度平台。平台架构分为 “调度中心” 和 “执行器”。调度中心类似定时任务的注册中心&a…

SuperMap iDesktop 之 BIM优化流程——建筑篇

kele 一、背景介绍 BIM数据是三维系统中的常客&#xff0c;它具有信息完备性、信息关联性、信息一致性、 可视化、协调性、模拟性、优化性和可出图性八大特点&#xff0c;广受人们喜爱&#xff0c;但这也使得它自身数据量庞大&#xff0c;在项目中展示效果不尽人意&#xff0c…

SegeX MemDialog:封装好的内存对话框(非资源对话框)说明

----哆啦刘小洋 原创&#xff0c;转载需说明出处 2022-12-27 SegeX MemDialog1 简介2 源文件清单3 快速测试4 实现基本原理5 主要功能6 使用方法6 .1 简单界面6.2 复杂界面1 简介 SegeX组件之一&#xff1a;SegeX MemDialog&#xff0c;应用级内存对话框封装类。源码首次公开。…

IEC 60598-2-22-2021 灯具 第2-22部分- 特殊要求-应急照明灯具.

2021年12月6日&#xff0c;国际电工委员会发布标准IEC 60598-2-22:2021《灯具-第2-22部分&#xff1a;特殊要求-应急照明灯具》。IEC 60598-2-22:2021标准以IEC 60598-2-22:2021 RLV标准的形式提供&#xff0c;包含国际标准及其红线版本&#xff0c;内容显示了与前一版本相比对…

tensorflow06——正则化缓解过拟合

正则化主要是在损失函数中引入了第二个部分&#xff0c;模型复杂度&#xff0c;具体就是对w参数赋予了权值&#xff0c;并求和&#xff0c;再乘上一个超参数。 &#xff08;利用给w加上权值&#xff0c;弱化训练数据的噪声&#xff09; 大概可以理解为这个意思假设模型有两个参…

从0-1搭建流媒体系统之ZLMediaKit 安装、运行、推流、拉流

音视频开发系列 文章目录音视频开发系列前言一、ZLMediaKit是什么&#xff1f;二、使用过程1.编译、安装、运行2.推流、拉流总结前言 目前、比较有名的流媒体服务器有ZLMediaKit、srs、live555、eadydarwin等。因为srs是单线程服务、对于多核服务器的支持需要通过部署多个服务…