当前位置:

首页 > 编程开发 > Java如何使用Lambda表达式?

Java如何使用Lambda表达式?

一、Lambda表达式的简介Lambda表达式(闭包):java8的新特性,lambda运行将函数作为一个方法的参数,也就是函数作为参数传递到方法中。使用lambda表达式可以让代码更加简洁。Lambda表达式的使用场景:用以简化接口实现。关于接口实现,可以有很多种方式来实现。例如:设计接口的实现类、使用匿名内部类。但是lambda表达式,比这两种方式都简单。packagetest;/***@author:Mercury*Date:2022/3/20*Time:17:48*Description:Lamb

    一、Lambda表达式的简介

    Lambda表达式(闭包):java8的新特性,lambda运行将函数作为一个方法的参数,也就是函数作为参数传递到方法中。使用lambda表达式可以让代码更加简洁。

    Lambda表达式的使用场景:用以简化接口实现。

    关于接口实现,可以有很多种方式来实现。例如:设计接口的实现类、使用匿名内部类。 但是lambda表达式,比这两种方式都简单。

    package test;
    /**
     * @author: Mercury
     * Date: 2022/3/20
     * Time: 17:48
     * Description:Lambda表达式
     * Version:1.0
     */
    public class Test04 {
        public static void main(String[] args) {
            //使用lambda表达式实现接口
            Test test = () -> {
                System.out.println("test");
            };
            test.test();
        }
    }
    interface Test{
        public void test();
    }

    二、Lambda表达式对接口的要求

    虽然说,lambda表达式可以在⼀定程度上简化接口的实现。但是,并不是所有的接口都可以使用lambda表达式来简洁实现的。

    lambda表达式毕竟只是⼀个匿名方法。当实现的接口中的方法过多或者多少的时候,lambda表达式都是不适用的。

    lambda表达式,只能实现函数式接口。

    1.函数式接口

    如果说,⼀个接口中,要求实现类必须实现的抽象方法,有且只有⼀个!这样的接口,就是函数式接口。

    代码如下(示例):

    //有且只有一个实现类必须要实现的抽象方法,所以是函数式接口
    interface Test{
        public void test();
    }

    2.@FunctionalInterface

    是⼀个注解,用在接口之前,判断这个接口是否是⼀个函数式接口。 如果是函数式接口,没有任何问题。如果不是函数式接口,则会报错。功能类似于 @Override。
    代码如下(示例):

    @FunctionalInterface
    interface Test{
        public void test();
    }

    3.Lambda表达式的语法

    1.Lambda表达式的基础语法

    lambda表达式,其实本质来讲,就是⼀个匿名函数。因此在写lambda表达式的时候,不需要关心方法名是什么。

    实际上,我们在写lambda表达式的时候,也不需要关心返回值类型。

    我们在写lambda表达式的时候,只需要关注两部分内容即可:参数列表和方法体

    lambda表达式的基础语法:
    (参数1,参数2,…) -> {
    方法体
    };

    参数部分:方法的参数列表,要求和实现的接口中的方法参数部分⼀致,包括参数的数量和类型。

    方法体部分 : 方法的实现部分,如果接口中定义的方法有返回值,则在实现的时候,注意返回值的返回。

    -> : 分隔参数部分和方法体部分。

    代码示例:

    package test;
    /**
     * @author: Mercury
     * Date: 2022/3/20
     * Time: 17:48
     * Description:Lambda表达式
     * Version:1.0
     */
    public class Test04 {
        public static void main(String[] args) {
            //使用lambda表达式实现接口
            //无参
    //        Test test = () -> {
    //            System.out.println("test");
    //        };
            //有参
    //        Test test = (name,age) -> {
    //            System.out.println(name+age+"岁了!");
    //        };
    //        test.test("小新",18);
            //有参+返回值
            Test test = (name,age)  -> {
                System.out.println(name+age+"岁了!");
                return age + 1;
            };
            int age = test.test("小新",18);
            System.out.println(age);
        }
    }
    //无参
    //interface Test{
    //    public void test();
    //}
    //有参 无返回值
    //interface Test{
    //    public void test(String name,int age);
    //}
    //有参 有返回值
    interface Test{
        public int test(String name,int age);
    }

    4.Lambda表达式的语法进阶

    参数部分的精简

    参数的类型

    由于在接口的方法中,已经定义了每⼀个参数的类型是什么。而且在使用lambda表达式实现接口的时候,必须要保证参数的数量和类 型需要和接口中的方法保持⼀致。因此,此时lambda表达式中的参数的类型可以省略不写。

    注意点:

    如果需要省略参数的类型,要保证:要省略, 每⼀个参数的类型都必须省略不写。绝对不能出现,有的参数类型省略了,有的参数类型没有省略。

            //有参+返回值
            Test test = (name,age)  -> {
                System.out.println(name+age+"岁了!");
                return age + 1;
            };
            int age = test.test("小新",18);
            System.out.println(age);

    参数的小括号

    如果方法的参数列表中的参数数量 有且只有⼀个,此时,参数列表的小括号是可以省略不写的。

    注意事项:

    • 只有当参数的数量是⼀个的时候, 多了、少了都不能省略。

    • 省略掉小括号的同时, 必须要省略参数的类型

            //一个参数
            Test test = name -> {
                System.out.println(name+"test");
            };
            test.test("小新");

    方法体部分的精简

    方法体⼤括号的精简

    当⼀个方法体中的逻辑,有且只有⼀句的情况下,⼤括号可以省略

    Test test = name -> System.out.println(name+"test");
            test.test("小新");

    return的精简

    如果⼀个方法中唯⼀的⼀条语句是⼀个返回语句, 此时在省略掉大括号的同时, 也必须省略掉return。

    Test test = (a,b) -> a+b;

    三、函数引用

    lambda表达式是为了简化接口的实现的。在lambda表达式中,不应该出现比较复杂的逻辑。如果在lambda表达式中出现了过于复杂的逻辑,会对程序的可读性造成非常大的影响。如果在lambda表达式中需要处理的逻辑比较复杂,⼀般情况会单独的写⼀个方法。在lambda表达式中直接引用这个方法即可。

    函数引用:引用⼀个已经存在的方法,使其替代lambda表达式完成接口的实现

    1.静态方法的引用

    语法:类::静态方法

    注意事项:

    • 在引用的方法后面,不要添加小括号。

    • 引用的这个方法,参数(数量、类型)和返回值,必须要跟接口中定义的⼀致

    package test;
    /**
     * @author: Mercury
     * Date: 2022/3/20
     * Time: 18:17
     * Description:lambda表达式静态方法引用
     * Version:1.0
     */
    public class Test05 {
        public static void main(String[] args) {
            //实现多个参数,一个返回值的接口
            //对一个静态方法的引用,语法:类::静态方法
            Test1 test1 = Calculator::calculate;
            System.out.println(test1.test(4,5));
        }
    }
    class Calculator{
        public static int calculate(int a,int b ){
            // 稍微复杂的逻辑:计算a和b的差值的绝对值
            if (a > b) {
                return a - b;
            }
            return b - a;
        }
    }
    interface Test1{
        int test(int a,int b);
    }
    package test;
    /**
     * @author: Mercury
     * Date: 2022/3/20
     * Time: 18:17
     * Description:lambda表达式静态方法引用
     * Version:1.0
     */
    public class Test05 {
        public static void main(String[] args) {
            //实现多个参数,一个返回值的接口
            //对一个静态方法的引用,语法:类::静态方法
            Test1 test1 = Calculator::calculate;
            System.out.println(test1.test(4,5));
        }
    }
    class Calculator{
        public static int calculate(int a,int b ){
            // 稍微复杂的逻辑:计算a和b的差值的绝对值
            if (a > b) {
                return a - b;
            }
            return b - a;
        }
    }
    interface Test1{
        int test(int a,int b);
    }

    2.非静态方法的引用

    语法:对象::非静态方法

    注意事项:

    • 在引用的方法后⾯,不要添加小括号。

    • 引用的这个方法, 参数(数量、类型) 和 返回值, 必须要跟接口中定义的⼀致。

    package test;
    /**
     * @author: Mercury
     * Date: 2022/3/21
     * Time: 8:14
     * Description:lambda表达式对非静态方法的引用
     * Version:1.0
     */
    public class Test06 {
        public static void main(String[] args) {
            //对非静态方法的引用,需要使用对象来完成
            Test2 test2 = new Calculator()::calculate;
            System.out.println(test2.calculate(2, 3));
        }
        private static class Calculator{
            public int calculate(int a, int b) {
                return a > b ? a - b : b - a;
             }
        }
    }
    interface Test2{
        int calculate(int a,int b);
    }

    3.构造方法的引用

    使用场景

    如果某⼀个函数式接口中定义的方法,仅仅是为了得到⼀个类的对象。此时我们就可以使用构造方法的引用,简化这个方法的实现。

    语法:类名::new

    注意事项:可以通过接口中的方法的参数, 区分引用不同的构造方法。

    package com.cq.test;
    /**
     * @author: Mercury
     * Date: 2022/4/27
     * Time: 10:31
     * Description:lambda构造方法的引用
     * Version:1.0
     */
    public class Test {
        private static class Dog{
            String name;
            int age;
            //无参构造
            public Dog(){
                System.out.println("一个Dog对象通过无参构造被实例化了");
            }
            //有参构造
            public Dog(String name,int age){
                System.out.println("一个Dog对象通过有参构造被实例化了");
                this.name = name;
                this.age = age;
            }
        }
        //定义一个函数式接口,用以获取无参的对象
        @FunctionalInterface
        private interface GetDog{
            //若此方法仅仅是为了获得一个Dog对象,而且通过无参构造去获取一个Dog对象作为返回值
            Dog test();
        }
        //定义一个函数式接口,用以获取有参的对象
        @FunctionalInterface
        private interface GetDogWithParameter{
            //若此方法仅仅是为了获得一个Dog对象,而且通过有参构造去获取一个Dog对象作为返回值
            Dog test(String name,int age);
        }
        // 测试
        public static void main(String[] args) {
            //lambda表达式实现接口
            GetDog lm = Dog::new; //引用到Dog类中的无参构造方法,获取到一个Dog对象
            Dog dog = lm.test();
            System.out.println("修狗的名字:"+dog.name+" 修狗的年龄:"+dog.age); //修狗的名字:null 修狗的年龄:0
            GetDogWithParameter lm2 = Dog::new;//引用到Dog类中的有参构造,来获取一个Dog对象
            Dog dog1 = lm2.test("萨摩耶",2);
            System.out.println("修狗的名字:"+dog1.name+" 修狗的年龄:"+dog1.age);//修狗的名字:萨摩耶 修狗的年龄:2
        }
    }

    四、Lambda表达式需要注意的问题

    这⾥类似于局部内部类、匿名内部类,依然存在闭包的问题。

    如果在lambda表达式中,使用到了局部变量,那么这个局部变量会被隐式的声明为 final。是⼀个常量,不能修改值。

    本文内容来源于互联网,如有侵权请联系删除。
    作者最新文章
    编程开发
    相关文章 更多
    关于AWSLambda中的冷启动,你想了解的信息都在这!
    关于AWSLambda中的冷启动,你想了解的信息都在这!

    原文:https://hackernoon.com/cold-starts-in-aws-lambda-f9e3432adbf0作者:Serhat Can译者:donghui关于AWS Lambda中的冷启动,有不少相关的博客文章。我正在进行一些研究,希望在此列出一些优质文章以及关键要点,以便大家能

    谷歌浏览器Mac版入口
    谷歌浏览器Mac版入口

    谷歌浏览器Mac版官方安装指南 谷歌浏览器Mac版官方安装入口是https://www.google.com/chrome/,需macOS 12+系统、500MB空间,下载.dmg后拖入应用程序安装,支持多设备同步、性能优化与隐私保护功能。 苹果电脑Chrome的安装入口究竟在哪里?这个问题最近可是

    Chrome浏览器JS脚本不运行怎么办
    Chrome浏览器JS脚本不运行怎么办

    Chrome中JavaScript未执行需依次检查:一、移除站点级禁用并添加允许域名;二、开启全局JavaScript开关;三、禁用干扰扩展;四、在开发者工具中启用JavaScript;五、重置内容设置为默认。 有时在Chrome里打开网页,会发现交互按钮点了没反应,数据加载不出来,页面仿佛“静止”

    IE浏览器怀旧版在线网址
    IE浏览器怀旧版在线网址

    IE浏览器怀旧版在线网址:一次精准的技术时光回溯 最近,不少老用户和怀旧爱好者在反复搜索一个问题:那个经典的Internet Explorer,如今还能在哪里原汁原味地体验到?答案指向一个特定的地址:https://ie.microsoft.com/legacy/。 这个网站远不止是一个简单的“皮肤

    火狐浏览器有哪些设置功能
    火狐浏览器有哪些设置功能

    火狐浏览器五大核心设置功能:解锁高效、安全与个性化体验 火狐浏览器功能强大,但如果不仔细挖掘,很多能大幅提升效率和安全性的设置可能就“藏着掖着”了。这就好比拥有一台高性能设备,却只用了基础模式。那么,如何把它调整到最顺手、最安全的状态?接下来,我们就聚焦于当前版本(截至2025年末)最关键的五大设置

    chrome搜索免验证入口
    chrome搜索免验证入口

    Chrome官方免验证入口为https://www.google.cn/chrome/,提供全平台安装包、免登录即用、本地化安全机制及引擎级性能优化。 到底该去哪里找正版、免费且无需繁琐验证的Chrome浏览器入口?这个问题困扰了不少网友。今天,我们就来直通核心,为大家详细拆解Chrome引擎的官方

    AWSLambda取消代码存储配额,别误会:函数大小限制没变
    AWSLambda取消代码存储配额,别误会:函数大小限制没变

    亚马逊云科技最近宣布为 Lambda 推出自管理代码存储,让函数和层可以直接引用客户自有 S3 存储桶中的部署包,而不必将其存放在 Lambda 管理的存储空间中。这一变化取消了每个区域的代码存储配额,过去,运行大规模函数集群的团队通常需要通过提交支持工单来提高这一配额;同时,Lambda 管理的存

    java heap space 选型思路:使用场景与区别整理
    java heap space 选型思路:使用场景与区别整理

    Java堆是JVM存储对象的核心内存区域,配置需结合场景:单体应用适中设置;大数据处理需大堆并关注GC停顿;微服务强调快速启动;高并发需精细划分堆区域。关键参数-Xms和-Xmx建议等值以稳定性能。垃圾回收器选择影响效率,如G1适用于大堆,ZGC可实现低停顿。内存错误时需监控堆状态。

    java heap space 使用中遇到的问题怎么解决
    java heap space 使用中遇到的问题怎么解决

    Java堆内存溢出错误通常因内存泄漏、数据处理需求过大或JVM参数配置不当引起。排查时可借助jmap、堆转储及MAT等工具定位问题。解决方案包括调整JVM内存参数(如-Xmx)、修复代码中的内存泄漏、优化大数据处理逻辑,并建立持续监控与预防机制,以保障应用稳定运行。

    java xml 选型思路:使用场景与区别整理
    java xml 选型思路:使用场景与区别整理

    XML在Java开发中用于配置、数据交换等场景。解析方式主要有DOM、SAX、StAX及第三方库。DOM适合操作小文件,SAX/StAX适合处理大文件流,JAXB用于对象与XML映射。选型需结合数据大小、内存、性能及团队熟悉度,现代框架常封装底层解析。

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    macOS软件
    macOS软件

    正软商城macOS软件专区,精选适用于Mac电脑的办公、设计、影音、效率、开发和系统工具,提供软件功能介绍、macOS兼容版本、正版授权及购买下载服务。

    Mac软件 更多
    灵活计算器
    灵活计算器
    macOS/iOS/Android

    灵活计算器是一款笔记式算数应用,支持实时计算、动态关联和云端同步功能。记录、整理和输出之间的过渡会更自然,适合长期写作、做笔记或持续沉淀个人内容。

    赤友清理大师
    赤友清理大师
    macOS

    赤友清理大师是一款为 Mac 设计的智能清理优化工具,可精准扫描垃圾、大文件、重复文件等,释放磁盘空间。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。

    极度公式
    极度公式
    Windows/macOS/Linux

    极度公式是一款跨平台专业LaTeX公式识别编辑软件,支持OCR公式识别和多平台编辑。和使用说明,避免使用,享受完整功能与稳定支持。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。

    WINDOWS 更多
    Windows 10
    Windows 10
    Windows

    Windows 10 是一款微软推出的经典操作系统,拥有硬件兼容性与多任务处理能力。它更偏向把系统状态查看和常用调节动作放在一起,适合需要持续观察和微调设备状态的场景。

    极度公式
    极度公式
    Windows/macOS/Linux

    极度公式是一款跨平台专业LaTeX公式识别编辑软件,支持OCR公式识别和多平台编辑。和使用说明,避免使用,享受完整功能与稳定支持。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。

    密码键盘
    密码键盘
    Windows/macOS/iOS/Android

    密码键盘是一款兼具安全性与便捷性的高效密码管理器。日常使用里的持续防护和信息管理会更突出,适合把安全控制放进长期使用流程中的场景。