02-JDK新特性-Lambda表达式

JDK新特性

Lambda表达式

什么是Lambda表达式

Lambda表达式是一个匿名代码块,用于简单的传递一段代码片段。

Lambda表达式标准格式

格式:(形式参数) -> {代码块}

  • 形式参数

    如果有多个参数,参数只见用逗号隔开;如果没有,留空即可
  • ->

    由英文中画线和大于符号组成,固定写法。代表指向动作。
  • 代码块

    是我们具体要做的事情,也就是我们以前写的方法体内容
// 组成Lambda表达式的三要素:形式参数,箭头,代码块
// 示例 
new Thread(() -> System.out.println("这是一个示例")).start();

Lambda表达式的使用前提

  • 有一个接口
  • 接口中有且仅有一个抽象方法

理解Lambda表达式

定义一只接口(Eatable),里面定义一个抽象方法:void eat();表示吃这一个动作。
然后以实现类,匿名内部类,Lambda表达式分别实现一下小明吃饭了这一动作。

通用接口 Eatable.java
package demo01;

/**
 * 定义吃接口
 *
 * @author Anna.
 * @date 2024/3/31 22:35
 */
public interface Eatable {
    /**
     * 吃
     *
     * @param
     * @return void
     * @author Anna.
     * @date 2024/3/31 22:35
     */
    void eat();
}
实现类方式实现

创建一个实现类(EatImpl)实现(Eatable)接口

package demo01;

/**
 * 吃实现类
 *
 * @author Anna.
 * @date 2024/3/31 22:37
 */
public class EatImpl implements Eatable{
    @Override
    public void eat() {
        System.out.println("通过实现类-小明吃东西了");
    }
}

测试代码

package demo01;

import java.util.Arrays;

/**
 * Demo01:
 * 定义一只接口(Eatable),里面定义一个抽象方法:void eat();表示吃这一个动作。
 * 然后以实现类,匿名内部类,Lambda表达式分别实现一下小明吃饭了这一动作。
 *
 * @author Anna.
 * @date 2024/3/31 22:36
 */
public class LambdaDemo01 {
    public static void main(String[] args) {
        // 通过实现类实现
        Eatable eat = new EatImpl();
        eat.eat();
    }
}

执行结果

在这里插入图片描述

匿名内部类方式实现

测试代码

package demo01;

import java.util.Arrays;

/**
 * Demo01:
 * 定义一只接口(Eatable),里面定义一个抽象方法:void eat();表示吃这一个动作。
 * 然后以实现类,匿名内部类,Lambda表达式分别实现一下小明吃饭了这一动作。
 *
 * @author Anna.
 * @date 2024/3/31 22:36
 */
public class LambdaDemo01 {
    public static void main(String[] args) {
        // 匿名内部类方式实现
        eat(new Eatable() {
            @Override
            public void eat() {
                System.out.println("通过匿名内部类方式实现-小明吃东西了");
            }
        });
    }

    /**
     * 定义一个调用Eatable接口eat()的方法
     *
     * @param eatable
     * @return void
     * @author Anna.
     * @date 2024/3/31 22:50
     */
    private static void eat(Eatable eatable){
        eatable.eat();
    }
}

执行结果

在这里插入图片描述

Lambda表达式实现

测试代码

package demo01;

import java.util.Arrays;

/**
 * Demo01:
 * 定义一只接口(Eatable),里面定义一个抽象方法:void eat();表示吃这一个动作。
 * 然后以实现类,匿名内部类,Lambda表达式分别实现一下小明吃饭了这一动作。
 *
 * @author Anna.
 * @date 2024/3/31 22:36
 */
public class LambdaDemo01 {
    public static void main(String[] args) {
        // Lambda表达式实现
        eat(() -> {
            System.out.println("通过Lambda表达式实现-小明吃东西了");
        });
    }

    /**
     * 定义一个调用Eatable接口eat()的方法
     *
     * @param eatable
     * @return void
     * @author Anna.
     * @date 2024/3/31 22:50
     */
    private static void eat(Eatable eatable) {
        eatable.eat();
    }
}

执行结果

在这里插入图片描述

对比实现类,匿名内部类,Lambda表达式编译文件

在这里插入图片描述

通过实现类方式实现,会生成EatImpl.class文件

通过匿名内部类方式实现,会生成LambdaDemo01$1.class匿名内部类文件

通过Lambda方式实现,不会额外生成文件,实现字节码会动态生成

Lambda表达式的省略模式

省略规则:

  1. 参数类型可以省略,但是多个参数的情况下,不能只省略一个
  2. 如果参数有且仅有一个,那么小括号可以省略
  3. 如果代码块的语句只有一条,大括号和分号可以省略,甚至是return

测试代码

package demo02;

import demo01.Eatable;

/**
 * Demo02:
 * Lambda表达式省略模式
 *
 * @author Anna.
 * @date 2024/3/31 22:36
 */
public class LambdaDemo02 {
    public static void main(String[] args) {
        // 正常调用
        System.out.println("=========正常调用=========");
        eat(() -> {
            System.out.println("小明吃东西了");
        });
        sum((int x, int y) -> {
            return x + y;
        });
        sleep((String name) -> {
            System.out.println(name + "睡觉了");
        });

        // 省略模式
        System.out.println("=========省略模式=========");
        System.out.println("=========参数类型可以省略=========");
        sleep((name) -> {
            System.out.println(name + "睡觉了");
        });
        // 参数类型可以省略,但是多个参数的情况下,不能只省略一个
        System.out.println("=========参数类型可以省略,但是多个参数的情况下,不能只省略一个=========");
        sum((x, y) -> {
            return x + y;
        });

        // 如果参数有且仅有一个,那么小括号可以省略
        System.out.println("=========如果参数有且仅有一个,那么小括号可以省略=========");
        sleep(name -> {
            System.out.println(name + "睡觉了");
        });

        // 如果代码块的语句只有一条,大括号和分号可以省略
        System.out.println("=========如果代码块的语句只有一条,大括号和分号可以省略=========");
        sleep(name -> System.out.println(name + "睡觉了"));

        // 如果代码块的语句只有一条,且有返回值 return 也可以省略
        System.out.println("=========如果代码块的语句只有一条,且有返回值 return 也可以省略=========");
        sum((x, y) -> x + y);
    }

    /**
     * 定义一个调用Eatable接口eat()的方法
     *
     * @param eatable
     * @return void
     * @author Anna.
     * @date 2024/3/31 23:11
     */
    private static void eat(Eatable eatable) {
        eatable.eat();
    }

    /**
     * 定义一个调用Sumable接口sum()的方法
     *
     * @param sumable
     * @return void
     * @author Anna.
     * @date 2024/3/31 23:11
     */
    private static void sum(Sumable sumable) {
        System.out.println(sumable.sum(20, 30));
    }

    /**
     * 定义一个调用Sleepable接口sleep()的方法
     *
     * @param sleepable
     * @return void
     * @author Anna.
     * @date 2024/3/31 23:11
     */
    private static void sleep(Sleepable sleepable) {
        sleepable.sleep("小明");
    }
}

执行结果

在这里插入图片描述

Lamda表达式的方法引用

学习lamda千万不要注意方法,一定要关心方法的入参的个数和类型以及出参的类型,不要关注方法的名称
方法引用被分为了好几类:

  1. 静态方法引用 Class::methodName
  2. 实例方法引用 objInstance::methodName
  3. 引用类中的非静态方法:Class::methodName
  4. 引用类的构造方法:Class::new 其中Class就是类名,后面跟“::new”,这个是固定写法哈,即使为了new一个对象出来

Sumable.java

package demo3;

public interface Sumable {
    int sum(int x, int y);
}

SumImpl.java

package demo3;

public class SumImpl implements Sumable {

    @Override
    public int sum(int x, int y) {
        return x + y;
    }
}

SumUtils.java

package demo3;

public class SumUtils {
    public int sum(int x, int y) {
        return x + y;
    }
}

IEntityDo.java

package demo3;

public interface IEntityDo {
    SumEntity init(int x, int y);
}

SumEntity.java

package demo3;

public class SumEntity {
    private int x;
    private int y;

    public SumEntity(int x, int y) {
        this.x = x;
        this.y = y;
    }

    @Override
    public String toString() {
        return "SumEntity{" +
                "x=" + x +
                ", y=" + y +
                '}';
    }
}

LambdaDemo03.java

package demo3;

/**
 * Demo03:
 * Lambda表达式方法引用
 *
 * @author Anna.
 * @date 2024/3/31 22:36
 */
public class LambdaDemo03 {
    public static void main(String[] args) {
        System.out.println("Lambda方法");
        sum(((x, y) -> x + y));

        System.out.println("静态方法引用");
        sum(Integer::sum);

        System.out.println("实例方法引用");
        Sumable sumable = new SumImpl();
        sum(sumable::sum);
        System.out.println("如果该接口有且仅有一个抽象方法,还可以进一步省略::内容");
        sum(sumable);

        System.out.println("引用类中的非静态方法");
        SumUtils sumUtils = new SumUtils();
        sum(sumUtils::sum);

        System.out.println("引用类的构造方法");
        init(SumEntity::new);
    }

    /**
     * 定义一个调用Sumable接口sum()的方法
     *
     * @param sumable
     * @return void
     * @author Anna.
     * @date 2024/3/31 23:11
     */
    private static void sum(Sumable sumable) {
        System.out.println(sumable.sum(20, 30));
    }

    /**
     * 定义一个调用EntityDo接口init()的方法
     *
     * @param entityDo
     * @return void
     * @author Anna.
     * @date 2024/3/31 23:11
     */
    private static void init(IEntityDo entityDo) {
        System.out.println(entityDo.init(20, 30));
    }
}

执行结果

在这里插入图片描述

Lambda表达式优缺点

Java 8中引入了lambda表达式,使得代码编写更加简洁、优雅。lambda表达式是一个匿名函数,可以作为参数传递给方法或者存储在变量中。在Java中使用lambda表达式可以有以下优点和缺点:

优点

  1. 代码简洁:使用lambda表达式可以减少冗余的代码量,使得代码更加简洁明了。特别是在编写只有一个抽象方法的接口时,可以将其替换为lambda表达式。
  2. 促进函数式编程:lambda表达式使得函数式编程成为可能。函数式编程强调函数的纯粹性和不可变性,有助于减少副作用和提高代码的可维护性。通过lambda表达式,我们可以将函数作为一等公民,并在不改变状态的情况下进行操作。
  3. 更好的代码复用:使用lambda表达式可以更方便地实现代码的复用。可以将一段逻辑封装在一个lambda表达式中,然后在多个地方使用。
  4. 并行处理能力:在Java 8之前,要实现多线程或并行处理需要编写大量的代码。使用lambda表达式可以方便地编写并行处理的代码,充分利用多核处理器的性能。
  5. 提升代码可读性:lambda表达式将逻辑封装在一个更加紧凑的形式中,使得代码更易读。通过命名良好的lambda表达式,可以使代码的意图更加清晰。

缺点

  1. 学习成本:lambda表达式是一个新的概念,在Java中引入了新的语法。对于初学者来说,学习和理解lambda表达式需要一些时间和努力。
  2. 可读性差:虽然lambda表达式可以提升代码的可读性,但是过于复杂的lambda表达式可能反而降低代码的可读性。尤其是当lambda表达式包含多个参数、多行代码或复杂的逻辑时,可读性会受到影响。
  3. 调试困难:由于lambda表达式是匿名函数,调试时可能会更加困难。在调试过程中,无法直接跟踪lambda表达式的执行路径,可能会增加调试的难度。
  4. 性能问题:lambda表达式的性能可能比传统的方法调用略差。虽然这个差距很小,但是在某些高性能场景下可能会有所影响。

总结:

lambda表达式是Java 8引入的一项强大的功能,对于简化代码、促进函数式编程、提升代码可读性和代码复用等方面都有很大的帮助。

然而,它也存在着一些学习成本高、可读性差、调试困难和性能问题等缺点。

在使用lambda表达式时,需要根据具体情况权衡利弊,选择合适的使用方式。

gitee源码

git clone https://gitee.com/dchh/JavaStudyWorkSpaces.git

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

leetcode90. 子集 II

去重逻辑: 关键是画出递归树!当我们即将进入第二个2的递归的时候,发现isVisit数组是100,也就是说这俩重复的数是False,并且这俩在nums值相同,所以写出去重逻辑! class Solution { public:vector…

Mock.js的基本使用

mock顾名思义,就是模拟的意思,它模拟什么呢?假设我们在开发的过程中,我们需要使用到接口,但是后端接口并没有完善,那么我们就可以使用到mock.js,它可以随机生成数据,拦截AJAX请求&am…

mysql执行脚本导入表和数据后中文注释乱码解决

本人在使用不同版本下进行操作时,就会出现中文乱码的问题。例如我本地安装mysql8,服务器安装的是mysql5,然后本地连接服务器的mysql后,执行SQL脚本之后发现中文全部乱码 使用工具查看,注释也都是乱码 解决方案 本地…

vue 视频添加水印

1.需求背景 其实腾讯云点播的api也支持视频水印,但是只有单个水印,大概效果是这样子的,不满足我们的需求,我们的需求是需要视频中都是水印。 腾讯云点播水印 项目需求的水印(主要是防录屏,最后的实现效果是这样&…

AcWing 4405. 统计子矩阵:做题笔记

目录 暴力思路 代码 前缀和双指针 代码 解释 推荐博客 这道题的主要思路就是枚举所有的子矩阵,判断符合条件的子矩阵的个数。 暴力思路 我服了,其实我最开始没有想到 :枚举所有的子矩阵 这样一个很有总结性的要点。 我是想着哦我先…

重读Java设计模式: 深入探讨建造者模式,构建复杂对象的优雅解决方案

引言 在软件开发中,有时需要构建具有复杂结构的对象,如果直接使用构造函数或者 setter 方法逐个设置对象的属性,会导致代码变得冗长、难以维护,并且容易出错。为了解决这个问题,我们可以使用建造者模式。 一、建造者…

Jamba LLM模型:破解大型上下文窗口挑战的AI新星

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…

使用Postman进行websocket接口测试

因为最近要搞关于基于AI的文本接口测试.需要用到websocket协议,于是看了一下发现postman也可以测而且很方便 位置 File->New->WebSocket 可以看到不止WebSocket还支持其他的各种协议 使用 首先先点击connect进行连接 连接成功之后可以选择多种文本格式添加请求参数 每…

打开DICOM文件需要注意到的点

DICOM图片用来存储医学信息 我一般处理的是图像信息,总结一下踩过的坑 打开DICOM文件需要注意到的点 DICOM图片使用python进行打开一定要注意窗口问题,dicom文件里面存储了很多其他的附加信息,不仅仅是图片,其中最重要的一个条就…

力扣刷题Days29-128.最长连续数列(js)

目录 1,题目 2,代码 2.1自己实现 2.2哈希表 3,学习与收获 枚举思想: 遍历的核心逻辑 碎碎念 本题 先是想到利用数组排序,从而简化遍历处理逻辑,再在提交错误提醒的情况下,考虑到数组中存…

Tab切换(Html+JavaScript+Css)

1.CSS样式 <style>* {margin: 0;padding: 0;}.tab {width: 590px;height: 340px;margin: 20px;border: 1px solid #e4e4e4;margin-left: 300px;}.tab-nav {width: 100%;height: 60px;line-height: 60px;display: flex;justify-content: space-between;}.tab-nav h3 {font…

Zeppelin安装

Zeppelin是一个基于Web的开源数据分析可视化工具&#xff0c;它提供了一个交互式的笔记本界面&#xff0c;用于在大数据环境中进行数据探索、数据分析、数据可视化和协作。Zeppelin的主要特点包括多语言支持、可视化功能、数据共享和协作&#xff0c;以及扩展性。它支持多种编程…

C++ 数组 结构编程题

一 求100以内的所有素数 /* * 需要标记2~100 之间的数是否处理 * 用数组&#xff0c;初始为0 表示都是素数&#xff0c;如果 判断为合数则置为1过用 */ #include<stdio.h> #include<math.h> int main() {const int n 100;int isPrim[n 1] { 0 };int i, j;for (…

C++ MFC

C是一种静态数据类型检查的、支持多重编程范式的程序设计语言&#xff0c;支持过程化程序设计、数据抽象、面向对象程序设计、制作图标等泛型程序设计的多种程序设计风格。 MFC(Microsoft Foundation Classes)&#xff0c;是一个微软公司提供的类库&#xff0c;以C类的形式封装…

JAVAEE之CSS

1.CSS 是什么&#xff1f; 层叠样式表 (Cascading Style Sheets). CSS 能够对网页中元素位置的排版进行像素级精确控制, 实现美化页面的效果. 能够做到页面的样式和结构分离. 1.1 CSS和HTML的区别 CSS&#xff0c;全称为层叠样式表(Cascading Style Sheets)&#xff0c;是…

【Spring Boot 源码学习】ConditionEvaluationReport 日志记录上下文初始化器

《Spring Boot 源码学习系列》 ConditionEvaluationReport 日志记录上下文初始化器 一、引言二、往期内容三、主要内容3.1 源码初识3.2 ConditionEvaluationReport 监听器3.3 onApplicationEvent 方法3.4 条件评估报告的打印展示 四、总结 一、引言 上篇博文《共享 MetadataRe…

redis和数据库数据不一直问题,缓存常见的三大问题

文章目录 数据一致性缓存常见问题缓存穿透缓存击穿缓存雪崩 数据一致性 1 思路 查询数据的时候&#xff0c;如果缓存未命中&#xff0c;则查询数据库&#xff0c;将数据写入缓存设置超时时间修改数据时&#xff0c;先修改数据库&#xff0c;在删除缓存。 2 代码实现 修改更…

【原创】基于分位数回归的卷积长短期结合注意力机制的神经网络(CNN-QRLSTM-Attention)回归预测的MATLAB实现

基于分位数回归的卷积长短期结合注意力机制的神经网络&#xff08;CNN-QRLSTM-Attention&#xff09;是一种用于时间序列数据预测的深度学习模型。该模型结合了卷积神经网络&#xff08;CNN&#xff09;、长短期记忆网络&#xff08;LSTM&#xff09;和注意力机制&#xff08;A…

P1803 凌乱的yyy / 线段覆盖(贪心)

思路&#xff1a; 这道题让求区间覆盖&#xff0c;它要求只能一个一个的区间&#xff0c;先对n个区间进行排序&#xff0c;按照区间的结束点前后进行排序。所以从后往前看结束时间点&#xff0c;如果下一个的起点在前一个的结束点之后&#xff0c;则数量加1。 代码&#xff1a…

Python进阶编程 --- 1.类和对象

文章目录 第一章&#xff1a;1.初始对象1.1 使用对象组织数据1.2 类的成员方法1.2.1 类的定义和使用1.2.2 创建类对象1.2.3 成员变量和成员方法1.2.4 成员方法的定义语法1.2.5 注意事项 1.3 类和对象1.3.1 基于类创建对象 1.4 构造方法1.5 其他内置方法1.5.1 魔术方法str字符串…