Lambdda表达式( Java 8 )

2023-10-31

在Java的语言世界里面,除了基本的数据类型,一切都是对象,例如:String字符串、每个对象实例、数组这些都是对象。在Java中方法是不能完全独立存在的,不能将方法作为参数或者返回值给实例。注意:方法(Method),函数(Function),在Java中是没有函数的,因为Java是一个面向对象编程的语言;函数更多的意义是用来表述面向过程的语言;又或者说"函数是大家的函数,方法是类的方法",不过,不用这么纠结,我们可以认为在Java中方法就是函数,函数就是方法。

为什么出现Lambda表达式

从线程的构建、自定义比较器、Swing等等,这些我们都是匿名内部类的方式去书写。为了简化这些代码的书写,使得代码更加紧凑,更为了使得Java拥有函数式编程的特点。javaScript是典型的函数式编程语言,点击这里以及这里了解,函数式语言提供了一种强大的功能–闭包,闭包的特点是词法的作用域与把函数当作值来传递。虽然闭包与Lambda表达式之间存在显著差别,但是Lambda表达式至少是很好的闭包替代者。

Lambda表达式是什么

在Java中,刚开始说过,除了基本的数据类型,一切都是对象,那么Lambda表达式也是对象,所以必须依赖于一种特殊的对象类型–函数式接口(Function Interface)。Lambda表达式可以理解为刚开始说的匿名内部类函数,它没有声明方法,没有访问修饰符,没有返回值声明和名字。

Lambda表达式的特征

  • 可选型声明:不需要声明参数类型,编译器可以统一识别参数值;
  • 可选的参数圆括号:一个参数且类型可推导时,无需定义圆括号,但是多个参数需要定义圆括号;
  • 可选的大括号:如果函数主体包含了一个语句,不需要大括号;
  • 可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要显式指定表达式返回值。

Lambda表达式的用法

  • Lambda表达式语法:(parameters)->expression 或 (parameters)->{statements}
    Lambda表达式语法解析:parameters:参数 expression:表达式(一条语句) statements:陈述(多个语句)

  • 用法
    1. 替代匿名内部类

      实现Runnable接口是匿名内部类的典型例子
      ```java
      // 代码示例
      public void runable() {
          new Thread(new Runnable() {
              @Override
              public void run() {
                  System.out.println("the old runnable now is useing");
              }
          }).start();
    
          new Thread(() -> System.out.println("the new runnable now is useing")).start();
      }
      ```
    

    2. 集合的迭代

      使用Lambda表达式对map集合进行迭代遍历
      ```java
      // 代码示例
      private void listiterator() {
          List<String> languages = Arrays.asList("java", "python", "javaScript");
          languages.forEach(x -> System.out.println(x));
      }
      ```
    

    3. 实现map

      使用Lambda表达式实现map,map的作用是把一个对象换做另一个,这块涉及到Java8的新特性Stream,下一篇博客会讲。
      ```java
      // 代码示例
      private void mapFunction(){
          List<Double> languages = Arrays.asList(2.0, 4.0, 6.0);
          languages.stream().map(x -> x + x * 0.5).forEach((x) -> System.out.println(x));
      }
      ```
    

    4. 实现reduce

      使用Lambda表达式实现reduce,reduce是将所有的值合并为一个,这块涉及到Java8的新特性Stream,下一篇博客会讲。
      ```java
      // 代码示例
      private void sumFunction() {
          List<Double> cost = Arrays.asList(2.0, 4.0, 6.0);
          double doubleCode = cost.stream().reduce((sum, x) -> sum + x).get();
          System.out.println(doubleCode);
      }
      ```
    

    5. 过滤操作

      使用Lambda表达式实现对集合的过滤,filter过滤掉集合中的部分元素,这块涉及到Java8的新特性Stream,下一篇博客会讲。
      ```java
      // 代码示例
      private void filterFunction() {
          List<Double> cost = Arrays.asList(2.0, 4.0, 6.0);
          //方式一
          cost.stream().filter(x -> x > 3).collect(Collectors.toList()).stream().forEach(x -> System.out.println(x));
          //方式二
          List<Double> doubleCode = cost.stream().filter(x -> x > 3).collect(Collectors.toList());
          doubleCode.stream().forEach(x -> System.out.println(x));
      }
      ```
    

    6. 与工具包java.util.function配合
      
      除了在语言层面支持了函数式编程,而且增添了一个新包,包名叫java.util.function。该包包含了很多类,来支持Java的函数式编程,其中一个类是Predicate,使用java.util.function.Predicate 函数式接口以及lambda表达式,可以向API方法添加逻辑,用更少的代码支持更多的动态行为。Predicate接口非常适用于做过滤。该包下的其他类放到姐妹篇里面讲解

函数式接口名 作用
Function<T, R> 接受一个参数T,返回结果R
Predicate 接受一个参数T,返回boolean
Supplier 不接受任何参数T,返回结果T
Consumer 接受一个参数T,不返回结果
UnaryOperator 继承自Function<T,T>,返回相同类型T的结果
BiFunction<T, U, R> 接收两个参数T,U,返回结果R
BinaryOperator 继承自BiFunction<T,T,T>,返回相同类型T的结果
Runnable 实际上不接受任何参数,也不返回结果
Comparable 实际上是接受两个相同类型的T,返回int
Callable 不接受任何参数,返回结果V
    ```java
    // 代码示例
    public class test {

        public static void main(String[] args) {
            test t = new test();

            List<String> launges = Arrays.asList("java", "shell", "python");
            t.functionTest.apply(launges).stream().forEach(x -> System.out.println(x));

            boolean flg = t.predicateTest.test(launges);
            System.out.println(flg);

        }

        private Function<List<String>, List<String>> functionTest = in -> {
            return in.stream().filter(x -> x.startsWith("j")).collect(Collectors.toList());
        };

        private Predicate<List<String>> predicateTest = in -> {
            return in.stream().filter(x -> x.startsWith("j")).count() > 0;
        };
    }
    ```

Lambda表达式的优劣

  • 优势
    1. 代码简洁
    2. 易并行计算
    3. 方便了函数式编程
    4. 改善了集合的操作(引入了Stream API)
  • 劣势
    1. 代码可读性变差
    2. Debug调试变得困难
    3. 不可以直接在foreach中修改外面的值
    4. 在很多非并行运算中,性能未必有传统的for性能要高

文章借鉴处

  • https://www.cnblogs.com/ysySelf/p/10937725.html
  • https://www.runoob.com/java/java8-lambda-expressions.html
  • http://blog.oneapm.com/apm-tech/226.html
  • https://objcoding.com/2019/03/04/lambda/
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Lambdda表达式( Java 8 ) 的相关文章

  • 有没有更简单的方法来分割/重建字符串?

    目前我正在使用String split 像这样 String tmp props get i getFullName split String name for int j 1 j lt tmp length j if j gt 1 nam
  • 如何在JavaFX中有效地滚动和缩放大图像?

    作为图像处理应用程序的一部分 我需要创建具有缩放 滚动和矢量叠加功能的简单查看器模块 图像相当大 40000x20000 这使得 ImageView 上的操作变慢 缓冲等 在 JavaFX 中处理巨大图像时 改善用户体验的最佳选项是什么 我
  • Java:while循环冻结程序

    我正在制作一个游戏 我需要每 3 秒更新一次 JProgressBar 为此 我使用 while 循环 问题是我的程序由于 while 循环而冻结 我在其他问题中读到它 他们没有帮助我解决这个问题 我不知道如何解决 这是我的代码 publi
  • 解析 (yyyy-MM-dd) 格式的字符串日期

    我有一个 2013 09 18 形式的字符串 我想将其转换为 java util Date 我正在做这个 SimpleDateFormat sdf new SimpleDateFormat yyyy MM dd Date converted
  • 模式更新后 jOOQ 生成的类的运行时验证?

    我用org jooq util DefaultGenerator在构建过程中生成 jOOQ 类来表示我的数据库模式 当应用程序运行时 架构预计会在应用程序不知情的情况下发生更改 此类更改可能与已生成的代码兼容 也可能不兼容 如何在运行时检测
  • Android:TelephonyManager 类

    我不明白为什么 API 文档中这么写TelephonyManager类是public 但是当我尝试创建一个实例时 它说它不是公共类 并且无法从包中访问 我看到它也说使用Context getSystemService Context TEL
  • 在 libgdx 中渲染 box2d

    我有一个使用 FitViewport 的大小为 800x480 的游戏世界 并且最初使用像素渲染 box2d 实体 固定装置 因此所有物理效果都显得浮动且缓慢 查看文档后 我意识到 box2d 使用度量单位 因此我将 box2d 位置和大小
  • SSLContext 初始化

    我正在看JSSE参考指南 我需要获取一个实例SSLContext为了创建一个SSLEngine 所以我可以使用它Netty以启用安全性 获取实例SSLContext I use SSLContext getInstance 我看到该方法被重
  • 合并和颜色样式不适用于 Apache POI excel 2003 格式

    在 Apache POI 中 我为某些单元格应用了一些样式并合并了这些单元格 当我在 2010 年或 2007 年打开时 它工作正常 但在 2003 年 格式样式消失了 每次保存 2003 Excel 文件之前都会弹出兼容性检查对话框 请参
  • 我可以使用 Selenium Webdriver 测试元素的顺序吗?

    有一个表单 其中有 3 个字段 具有 3 个不同的 ID fieldset div div fieldset
  • ThreadPoolExecutor 和队列

    我以为使用线程池执行器 http docs oracle com javase 6 docs api java util concurrent ThreadPoolExecutor html我们可以提交Runnables 要在以下位置执行B
  • 在 java 8 下使用泛型出现类型错误,但在 java 7 下则不然

    我有一段代码可以在 java 7 下编译良好 但不能在 java 8 下编译 这是一个独立的重现示例 我已经采用了显示此问题的真实代码并删除了所有实现 import java util Iterator class ASTNode
  • 使用 Haskell 将函数注入到 Java .class 文件中

    我使用 Haskell 编写了一个 Java 字节码解析器 它工作得很好 然而下一步让我完全难住了 我的 Haskell 程序需要修改 class 文件 以便在执行时 Java 程序打印 输入 此处的方法名称 在执行方法之前 并且 退出 此
  • 为什么replaceAll在这行代码中不起作用? [复制]

    这个问题在这里已经有答案了 String weatherLocation weatherLoc 1 toString weatherLocation replaceAll how weatherLocation replaceAll wea
  • gwt 文本框添加更改处理程序

    我有一个从设计师那里收到的文本框 但是我在 GWT 中编写了操作 问题是文本框为空 但是当通过按下按钮用值填充文本框时 将显示警报框 通知值已更改 但没有成功 帮助我 TextBox zip1 null function onModuleL
  • 短 2 个字节

    我正在从串行端口读取一个长度为 133 字节的数据包 最后 2 个字节包含 CRC 值 我使用 Java 将 2 个字节值制成单个 我认为很短 这就是我所做的 short high 48 0x00ff short low 80 short
  • 将一个整数从 C 客户端发送到 Java 服务器

    我使用此代码将一个整数从我的 Java 客户端发送到我的 Java 服务器 int n rand nextInt 50 1 DataOutputStream dos new DataOutputStream socket getOutput
  • 按钮悬停和按下效果 CSS Javafx

    我是 CSS 新手 为按钮定义了以下 CSS 样式 其中id并且应用了自定义样式 但不应用悬停和按下效果 bevel grey fx background color linear gradient f2f2f2 d6d6d6 linear
  • Java有没有类似微软CHESS的工具?

    是否有类似于 Microsoft 的现有 Java 工具CHESS http research microsoft com chess 或者 CHESS 源代码是否开放 以便我可以尝试将其转换为 Java 谷歌的织线工 http code
  • removeall 和removeif 的用例

    我找到了这个 fun main val list MutableList

随机推荐

  • 【电源之美】DCDC三种工作模式:CCM、DCM、BCM

    DCDC的三种工作模式 CCM连续导通模式 DCM断续导通模式 BCM临界导通模式 CCM Continuous Conduction Mode 连续导通模式 在一个开关周期内 电感电流从不会到0 或者说电感从不 复位
  • 学习 Rust cookbook 之算法篇(algorithm)

    原文作者 suhanyujie 永久链接 https github com suhanyujie rust cookbook note 博客链接 https ishenghuo cnblogs com 学习 Rust cookbook 之算
  • synchronized底层原理

    一探究竟 反编译 三种使用场景 示例代码 public class SynchronizePrincipe public synchronized static void fun1 public synchronized void fun2
  • 【解决IDEA控制台中文乱码,亲测有效,分析全面】

    首先判断IDEA控制台乱码来源 自我总结 IDEA控制台输出日志乱码一般会有三种来源 1 IDEA本身编码错误 2 Tomcat日志输出编码错误 3 项目本身原因 终极原因是 将IDEA编码和Tomcat编码不一致 统一设置为UTF 8即可
  • 约瑟夫环问题『js实现』

    传说罗马人占领了乔塔帕特 41 个犹太人被围堵在一个山洞里 他们拒绝被俘虏 而决定集体自杀 大家决定了一个自杀方案 41 个人围成一个圈 由第 1 个人开始顺时针报数 每报数为 3 的人立刻自杀 然后再由下一个人重新从 1 开始报数 依旧是
  • react 图片剪切(react-easy-crop)

    antd 官方提供的剪切组件 仅支持本地图片的剪切和上传 import Upload from antd import ImgCrop from antd img crop import type RcFile UploadFile Upl
  • Angular中父子组件传值@Input @Output @ViewChild最全面最简单的总结

    父组件传递给子组件 值传递方式 Input既可以传递数据也可以传递方法 传递数据 不举例了 传递方法 父组件定义方法 parentRun alert 这是父组件的 run 方法 调用子组件时传入当前方法 是传递方法不是调用方法
  • Element UI el-input 只能输入大于0的正整数

    当输入值以0开头或者不为0 9的整数时 则用 替换掉 g表示全局匹配 则所有匹配项都会被替换掉 效果为不能输入以0开头或不为正整数的值
  • Oracle 基本 SQL 语句查询手册(1):增删改查

    关于SQL语法学习 这里有一份图文并茂的教程 点击此处 针对文字内容进行简化 通过注释 解释语句含义 本文的重点在于Oralce中写法 当然了 大部分写法都是通用的 查询手册 没有配图 各位看官见谅 创建临时表 用于测试 练习基本语句的写法
  • 什么是护网(HVV)?需要什么技术?(内附护网超全资料包)

    一 什么是护网行动 护网行动是以公安部牵头的 用以评估企事业单位的网络安全的活动 具体实践中 公安部会组织攻防两方 进攻方会在一个月内对防守方发动网络攻击 检测出防守方 企事业单位 存在的安全漏洞 通过与进攻方的对抗 企事业单位网络 系统以
  • ping 命令数字波动大的解决方法

    win10ping值不稳定怎么办 我们可以通过ping来判断网络是否流畅 一般来说在ping界面 只要 时间 后面的数值在10以内那么网速就是稳定的 最近在win10系统中有用户反应网速慢的心想 在使用ping进行ping一些网站的时候果然
  • easyUI前端框架tree(树)后台实现(树形菜单一)——java

    转载请标明出处 https blog csdn net men ma article details 106847165 本文出自 不怕报错 就怕不报错的小猿猿 的博客 easyUI前端框架tree 树 后台实现 树形菜单一 java 利用
  • 引领语言智能革命的巨型语言模型 ChatGPT PK Google Bard , Anthropic

    ChatGPT是由OpenAI公司训练的一个大型语言模型 它可以生成人类可读的文本 这是一个基于Transformer架构的预训练模型 可以进行语言生成和语言理解任务 OpenAI公司在2020年推出了ChatGPT 它是世界上最大的语言模
  • 多级代理下Nginx透传真实IP

    文章目录 多级代理下Nginx透传真实IP Nginx RealIP获取真实IP 多级代理下Nginx透传真实IP 1 基于代理 七层负载均衡 情况下 透传客户端的真实IP 环境 10 0 0 5 proxy node1 一级代理10 0
  • ERROR: Failed building wheel for dlib python 3.10 无法下载 pip/conda install dlib库的解决办法

    如果您在Python 3 10版本中无法使用pip安装dlib库 可能是由于以下原因之一 您的Python版本不支持dlib库 请确保您的Python版本与dlib库的版本兼容 您的pip版本不支持dlib库 请确保您的pip版本与dlib
  • plc模拟量与通信控制应用实践_第三版电气控制与PLC应用模块三教材答案

    很高兴这期为你分享干货 让你在困难中找到解决的线索 模块三答案 任务一 思考与练习 1 PLC 主要应用在哪些场合 答 1 开关量逻辑控制 2 模拟量过程控制 3 运动控制 4 现场数据采集处理 5 通讯联网 多级控制 2 PLC 的基本结
  • 文件打包发布

    本文基于VS Qt和VTK环境开发软件 生成可执行文件 通过软件ProcessExplorer查找发布软件所需要的库和通过软件VNISEdit打包该可执行文件 1 添加QT所需要的环境 2 添加VTK所需要的环境 3 文件打包发布 1 添加
  • windows上同时安装两个版本的mysql数据库

    在实际开发中 一些低版本数据库 不支持一些特殊的sql语句 因此高版本数据库数据导入低版本的时候就会出问题 因此 在一些特殊情况下 低版本数据库不能动 高版本mysql数据又无法导入低版本mysql 我们不得不在同一台机器上安装两个版本my
  • 关于使用get请求传递base64的注意事项

    关于使用get请求传递base64的注意事项 我们知道 get请求和post请求是有区别的 1 GET请求是用来请求获取数据 POST一般作为发送数据到后台时使用 并不返回数据 2 GET请求也可传参到后台 但是其参数在浏览器的地址栏的ur
  • Lambdda表达式( Java 8 )

    在Java的语言世界里面 除了基本的数据类型 一切都是对象 例如 String字符串 每个对象实例 数组这些都是对象 在Java中方法是不能完全独立存在的 不能将方法作为参数或者返回值给实例 注意 方法 Method 函数 Function