java lambda函数_Java SE 8新功能介绍:使用Lambda Expression进行函数式编程

java lambda函数

Java SE 8新功能浏览 ”系列的这篇文章将深入了解Lambda表达式 。 我将向您展示Lambda表达式的几种不同用法。 它们都具有功能接口的共同实现。 我将解释编译器如何从代码中推断信息,例如特定类型的变量以及后台实际发生的情况。

在上一篇文章“ Java SE 8新特性之旅:Java开发世界中的重大变化 ”中,我讨论了在本系列文章中我们将要探索的内容。 我首先介绍了Java SE 8的 主要功能 ,然后介绍了在Microsoft Windows和Apple Mac OS X平台上JDK8的安装过程 ,并提供了重要的建议和注意事项。

最后,我们开发了一个由Lambda表达式支持的控制台应用程序,以确保可能已经安装了Java SE 8。

源代码托管在我的Github帐户上:从此处克隆。

Lambda表达是什么?

Java SE 8的最著名的新功能也许叫做Project Lambda,它是将Java引入函数式编程领域的一项努力。

用计算机科学术语;


Lambda是一个匿名函数。 即,没有名称的功能。

在Java中;


所有函数都是类的成员,被称为方法。 要创建方法,您需要定义其所属的类。

Java SE 8中的lambda表达式使您可以使用非常简洁的语法定义一个类和单个方法,以实现具有单个抽象方法的接口。

让我们弄清楚这个想法。

Lambda Expressions使开发人员可以简化和缩短其代码。 使它更具可读性和可维护性。 这导致删除更多详细的类声明

让我们看一些代码片段。

  1. 实现接口:在Java SE 8之前,如果要创建线程,首先要定义一个实现可运行接口的类。 这是一个具有名为Run的抽象方法的接口,该抽象方法不接受任何参数。 您可以在其自己的代码文件中定义该类。 由MyRunnable.java命名的文件。 就像我在这里所做的那样,您可以将类命名为MyRunnable。 然后,您将实现单个抽象方法。
    public class MyRunnable implements Runnable {@Overridepublic void run() {System.out.println("I am running");}public static void main(String[] args) {MyRunnable r1 = new MyRunnable();new Thread(r1).start();}
    }

    在此示例中,我的实现将文字字符串输出到控制台。 然后,您将获取该对象,并将其传递给线程类的实例。 我将可运行对象实例化为名为r1的对象。 将其传递给线程的构造函数并调用线程的start方法。 现在,我的代码将在自己的线程和内存空间中运行。

  2. 实现内部类:您可以对此代码进行一些改进,而不是将类声明为单独的文件,而可以将其声明为使用该类的方法的局部使用类,即内部类
    public static void main(String[] args) {Runnable r1 = new Runnable() {@Overridepublic void run() {System.out.println("I am running");}};new Thread(r1).start();}

    所以现在,我再次创建一个名为r1的对象,但直接调用该接口的构造方法。 再一次,实现它是单个抽象方法。 然后,我将对象传递给线程的构造函数。

  3. 实现一个匿名类:并且可以通过将类声明为匿名类来使它更加简洁,这样命名是因为它从未被命名。 我正在实例化可运行的接口,并将其立即传递给线程构造函数。 我仍在实现run方法,并且仍在调用线程的start方法。
    public static void main(String[] args) {new Thread(new Runnable() {@Overridepublic void run() {System.out.println("I am running");}}).start();}
  4. 使用lambda表达式:Java SE 8中,您可以重构此代码以显着减少它并使它更具可读性。 lambda版本可能看起来像这样。
    public static void main(String[] args) {Runnable r1 = () -> System.out.println("I am running");new Thread(r1).start();}

    我正在声明具有可运行类型的对象,但是现在我使用一行代码来声明单个抽象方法实现,然后再次将对象传递给线程的构造函数。 您仍在实现可运行的接口并调用它的run方法,但使用的代码却少得多。 此外,它可以进行以下改进:

    public static void main(String[] args) {   new Thread(() -> System.out.println("I am running")).start();
    }

    这是有关Lambda项目的早期规格文档中的重要一句话。

    Lambda表达式只能出现在将它们分配给类型为功能接口的变量的位置。
    引用布莱恩·格茨

    让我们分解一下以了解发生了什么。

有哪些功能接口?

功能接口是仅具有一个自定义抽象方法的接口。 即,不是从对象类继承的对象。 Java有许多这样的接口,例如Runnable,Comparable,Callable,TimerTask等。

在Java 8之前,它们被称为Single Abstract MethodSAM接口 。 在Java 8中,我们现在将它们称为功能接口

Lambda表达式语法:

JDK8-SES-P2-1

这个lambda表达式返回了runnable接口的实现。 它有两部分,由称为箭头标记Lambda运算符的新语法分开。 lambda表达式的第一部分,在箭头标记之前,是您要实现的方法的签名。

在此示例中,这是一个无参数方法,因此仅用括号表示。 但是,如果我要实现一个接受参数的方法,则只需给出参数名称。 我不必声明它们的类型。

因为接口只有一个抽象方法,所以数据类型是已知的。 lambda表达式的目标之一是消除不必要的语法。 表达式的第二部分,在箭头标记之后,是单个方法主体的实现。

如果仅是一行代码(如本例所示),则您不需要任何其他内容。 要使用多个语句实现方法主体, 请将它们括在花括号中

Runnable r = ( ) -> {System.out.println("Hello!");System.out.println("Lambda!");};

Lambda目标:

Lambda表达式可以减少您需要编写的代码量以及必须创建和维护的自定义类的数量。

如果您要实现一次使用的接口,那么创建另一个代码文件或另一个命名类并不总是很有意义。 Lambda表达式可以定义一次匿名实现,以供一次性使用,并显着简化代码。

定义和实例化功能接口

为了开始学习Lambda表达式,我将创建一个全新的功能接口。 一个具有单个抽象方法的接口,然后我将使用Lambda表达式实现该接口。

您可以使用托管在github上的源代码项目“ JavaSE8-Features”来导航项目代码。

JDK8-SES-P2-2

  1. 没有任何参数的方法,Lambda实现

    在我的源代码中,我实际上将接口放入其自己的以lambda.interfaces结尾的子包中。 我将其命名为HelloInterface接口。为了实现带有lambda表达式的接口,它必须具有一个抽象方法。 我将声明一个返回void的公共方法,并将其命名为doGreeting 。 它不接受任何参数,这是使接口可用于Lambda表达式的全部工作。 如果需要,可以使用新的注释,该注释已添加到Java SE 8中,称为功能接口

    /**** @author mohamed_taman*/
    @FunctionalInterface
    public interface HelloInterface {void doGreeting();}

    现在,我准备在lambda.impl包下创建一个新类UseHelloInterface ,它将实例化我的功能接口( HelloInterface )如下:

    /*** @author mohamed_taman*/public class UseHelloInterface {public static void main(String[] args) {HelloInterface hello = ()-> out.println("Hello from Lambda expression");hello.doGreeting();}
    }

    运行文件并检查结果,它应该运行并输出以下内容。

    ------------------------------------------------------------------------------------
    --- exec-maven-plugin:1.2.1:exec (default-cli) @ Java8Features ---
    Hello from Lambda expression
    ------------------------------------------------------------------------------------

    因此,当您使用不接受任何参数的单个抽象方法时,代码就是这样。 让我们看一下带有参数的外观。

  2. 具有任何参数的方法,Lambda实现

    lambda.interfaces下 。 我将创建一个新接口并将其命名为CalculatorInterface 。 然后,我将声明一个返回void的公共方法,并将其命名为doCalculate ,它将接收两个整数参数value1value2

    /*** @author mohamed_taman*/@FunctionalInterface
    public interface CalculatorInterface {public void doCalculate(int value1, int value2);}

    现在,我准备在lambda.impl包下创建一个新类Use CalculatorInterface ,它将实例化我的功能接口( CalculatorInterface ),如下所示:

    public static void main(String[] args) {CalculatorInterface calc = (v1, v2) -> {int result = v1 * v2;out.println("The calculation result is: "+ result);};calc.doCalculate(10, 5);}

    注意doCalculate()参数,它们在接口中分别命名为value1和value2,但是您可以在此处为它们命名。 我将其命名为v1和v2。 我不需要在参数名称前插入int; 该信息是已知的,因为编译器可以从功能接口方法签名中推断出此信息。运行文件并检查结果,它应该运行并输出以下内容。

    ------------------------------------------------------------------------------------
    --- exec-maven-plugin:1.2.1:exec (default-cli) @ Java8Features ---
    The calculation result is: 50
    ------------------------------------------------------------------------------------
    BUILD SUCCESS

    始终牢记以下规则:

    同样,您必须遵循该规则,即接口只能具有一个抽象方法 然后,可以使用lambda表达式实现该接口及其单一抽象方法。

  3. 将内置功能接口与lambda结合使用

    前面已经描述了如何使用lambda表达式实现您自己创建的接口。现在,我将展示具有内置接口的lambda表达式。 属于Java运行时的接口。 我将使用两个示例。 我正在一个名为lambda.builtin的程序包中工作,这是练习文件的一部分。 我将从这堂课开始。 UseThreading 。 在此类中,我实现了Runnable接口。 这个接口是Java多线程体系结构的一部分,我的重点是代码的编写方式,而不是操作方式。 我将展示如何使用lambda表达式替换这些内部类。 我将注释掉声明两个对象的代码。 然后,我将重新声明它们并使用lambdas进行实现。 因此,让我们开始吧。

    public static void main(String[] args) {//Old version// Runnable thrd1 = new Runnable(){//  @Override
    //  public void run() {
    //    out.println("Hello Thread 1.");
    //  } 
    //};/******************************************* Using lambda expression inner classes *******************************************/Runnable thrd1 = () -> out.println("Hello Thread 1.");new Thread(thrd1).start();// Old Version/*new Thread(new Runnable() {@Overridepublic void run() {out.println("Hello Thread 2.");}}).start();*//******************************************** Using lambda expression anonymous class ********************************************/new Thread(() -> out.println("Hello Thread 2.")).start();}

    让我们看另一个例子。 我将使用比较器比较器是Java中的另一个功能接口,具有单个抽象方法。 此方法是比较方法。打开文件UseComparator类,并检查注释的代码位,这是将其重构为lambda表达式之前的实际代码。

    public static void main(String[] args) {List<string> values = new ArrayList();values.add("AAA");values.add("bbb");values.add("CCC");values.add("ddd");values.add("EEE");//Case sensitive sort operationsort(values);out.println("Simple sort:");print(values);// Case insensetive sort operation with anonymous class/*      Collections.sort(values, new Comparator<string>() {@Overridepublic int compare(String o1, String o2) {return o1.compareToIgnoreCase(o2);}});
    */// Case insensetive sort operation with Lambdasort(values,(o1, o2) -> o1.compareToIgnoreCase(o2));out.println("Sort with Comparator");print(values);}

    和以前一样,它不会为您提供任何性能优势 。 基本功能完全相同。 无论您声明自己的类 ,使用内部匿名内部类还是lambda表达式 ,完全取决于您。

在本系列的下一篇文章中,我们将探讨和代码如何使用lambda表达式, 过滤谓词接口的集合遍历方法引用 的集合 ,在接口实现的默认方法,并最终实现在接口的静态方法 遍历集合

资源:

  1. Java教程,Lambda表达式
  2. JSR 310:日期和时间API
  3. JSR 337:Java SE 8发行内容
  4. OpenJDK网站
  5. Java平台,标准版8,API规范

翻译自: https://www.javacodegeeks.com/2014/07/java-se-8-new-features-tour-functional-programming-with-lambda-expression.html

java lambda函数

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

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

相关文章

Apache Camel 3.1 –更多骆驼核心优化(第2部分)

我以前曾在博客中介绍我们在下一个Camel 3.1版本&#xff08;第1部分&#xff09;中所做的优化 。 今天&#xff0c;我想发布大约4周后的最新状态更新。 我们集中在三个方面优化骆驼核心&#xff1a; 不必要的对象分配 不必要的方法调用 提高绩效 换句话说&#xff0c;我…

计算机系统的指令系统,计算机指令系统指的是什么呢?

2014-12-27计算机系统的指令由你哪两部分组成&#xff1f;共作用分别是什么&#xff1f;1。8086汇编语言指令由标号、操作码、操作数和注释组成,其中标号和注释可以省略&#xff0c;操作码指出指令要过盛的功能,操作数指出完成的对象。2。变量和标号的区别是变量由伪指令定义&a…

echarts怎么保存图片到剪切板上_在电脑上怎么批量给图片编号以及怎么自动记录记事本txt文档时间...

电脑日益成为我们日常办公不可或缺的工具&#xff0c;除了必要的软件使用之外&#xff0c;也有一些直到今天还不那么为人所熟知的小技巧。而小编今天就暂时为大家介绍两个颇为常用的小技巧~分别是如何将图片批量编号以及自动记录记事本时间。技巧一、图片批量编号旅行或者活动结…

计算机类qq网名,最帅的qq名字

qq这个聊天工具已经成为人们电脑里必备的软件&#xff0c;上到40~50的叔叔阿姨&#xff0c;下至8~9岁的小学生&#xff0c;都有qq这个聊天工具。qq是有可以随意改名字的功能&#xff0c;最长可以输入十几个字符作为名字。就是因为取名没有太多的限制&#xff0c;反而让人不知道…

c++中求解非线性方程组_齐次线性方程组的基础解系的简便算法

线性方程组的求解是线性代数中的基本技能&#xff0c;而齐次线性方程组的基础解系的求法又是基础。本文给出一个计算齐次线性方程组的基础解系的公式&#xff0c;从而简化计算过程。01 符号说明 n元线性方程组的矩阵形式&#xff1a;(1)齐次线性方程组;(2)非齐次线性方程组;系数…

python的if语句例句_Python入门之if条件语句

Besides the while statement just introduced, Python knows the usual control flow statements known from other languages, with some twists.除了之前介绍的while语句&#xff0c;Python同样支持其他语言通常用的控制流语句&#xff0c;但也有一些区别。 if Statements P…

esp32 怎么分配freertos 堆栈大小_深度解剖~ FreeRtos阅读笔记2 任务创建、内核链表初始化...

2.FREERTOS任务创建、内核链表初始化硬件环境&#xff1a;cortex m4FreeRTOS版本:v8.0.1今天开始阅读freertos&#xff0c;阅读同时做下笔记&#xff0c;等哪天碰到移植问题再翻出来看看。2.1 任务、链表结构体源码中使用tskTCB来存储一个任务的所有信息&#xff0c;xLIST存储内…

Sigma IDE现在支持Python无服务器Lambda函数!

想想无服务器&#xff0c;使用Pythonic –全部在您的浏览器中&#xff01; &#xff08;好吧&#xff0c;这则新闻已经过了几周了&#xff0c;但是仍然……&#xff09; 如果您沉迷于整个无服务器的“事物”中 &#xff0c;您可能已经注意到我们&#xff0c;一个在SLAppForge臭…

idle不是python自带的开发工具_Python的开发工具

通常情况下&#xff0c;为了提高开发效率&#xff0c;需要使用相应的开发工具。进行Python开发也可以使用开发工具。下面将详细介绍Python自带的IDLE 一使用自带的IDLE 在安装Python后&#xff0c;会自动安装一个IDLE。它是一个Python shell(可以在打开的IDLE窗口的标题栏上看到…

java se 导原码_Java SE 8新功能导览:Java开发世界中的重大变化

java se 导原码我很自豪&#xff0c;像其他专业团队成员一样&#xff0c;是采用OpenJDK的成员之一&#xff0c;但是从过去8个月就加入了&#xff0c;我们经历了Java SE 8 开发&#xff0c;编译&#xff0c;编码&#xff0c;讨论等各个阶段&#xff0c;直到将其付诸实践为止。 。…

linux将日期和日历信息追加到文件中_Linux任务调度

crontab 任务调度crontab 进行定时任务的设置概述 任务调度&#xff1a;是指系统在某个时间执行的特定的命令或程序。任务调度分类&#xff1a;1.系统工作&#xff1a;有些重要的工作必须周而复始地执行&#xff0c;如病毒扫描等 。2.个别用户工作&#xff1a;个别用户可能希望…

android sdk build-tools_从零开始仿写一个抖音App——视频编辑SDK开发(一)

本文首发于微信公众号——世界上有意思的事&#xff0c;搬运转载请注明出处&#xff0c;否则将追究版权责任。交流qq群&#xff1a;859640274。大家好久不见&#xff0c;又有一个多月没有发文章了。不知道还有哪些读者记得我的 从零开始仿写抖音App 的系列文章&#xff0c;这个…

爱默生E系列服务器机柜托盘,艾默生通信电源PS48300-3B/1800 一体化室内机柜

PS48300-3B/1800电源系统PS48300-3B/1800电源系统是艾默生网络能源集多年开发和网上运行经验&#xff0c;采用 DSP控制技术&#xff0c;为满足3G网络需求而设计的高可靠、高功率密度、高性能、全数 字化通信电源系统。根据交流配电和机柜高度。一、特点 1、休眠节能专利技术&am…

功能Java示例 第8部分–更多纯函数

这是第8部分&#xff0c;该系列的最后一部分称为“ Functional Java by Example”。 我在本系列的每个部分中发展的示例是某种“提要处理程序”&#xff0c;用于处理文档。 在上一期文章中&#xff0c;我们已经使用Vavr库看到了一些模式匹配&#xff0c;并且还将故障也视为数据…

tensorflow 小于_坐姿不对,屏幕就变模糊!教你用TensorFlow做一款“隐形背背佳”...

大数据文摘出品作为一个上班族&#xff0c;每天坐在电脑前那么久&#xff0c;难免出现腰酸背痛的情况&#xff0c;时间长了甚至脊柱都歪曲变形了&#xff0c;这可不行&#xff01;一定要克制住自己的坐姿。这里有款“隐形背背佳”&#xff0c;要不要了解一下&#xff1f;一位名…

python里随机抽取样本_概率分布和抽样分布基础知识及Python实现

本文主要介绍推论统计中的概率分布和抽样分布,本文结构如下: 一、概率分布 随机变量:在一定条件下,某件事情可能发生或者不发生,这个事件就叫随机事件。例如抛硬币哪面朝上。随机变量X就是用来量化随机事件的函数,是将随机事件每一个可能出现的结果映射到数值的一个函数。…

php 创建目录_使用SMB绕过PHP远程文件包含限制

译文声明本文是翻译文章&#xff0c;文章原作者mannulinux&#xff0c;文章来源&#xff1a;mannulinux.org 原文地址&#xff1a;http://www.mannulinux.org/2019/05/exploiting-rfi-in-php-bypass-remote-url-inclusion-restriction.html译文仅供参考&#xff0c;具体内容表达…

eas系统服务器地址,EAS7.0EAS7.5服务端及其客户端标准配置介绍

金蝶EAS是基于JavaEE的大型企业应用。目前服务端支持以下主流软硬件环境。适用版本&#xff1a;EAS7.0 EAS703 EAS7.51.金蝶EAS服务端支持的软硬件环境注&#xff1a;标志为部署支持的环境&#xff0c;可以正常安装配置&#xff0c;但是正式运行前需联系金蝶技术支持。2.客户端…

Java的Kafka:构建安全,可扩展的消息传递应用程序

使用Okta的身份管理平台轻松部署您的应用程序 使用Okta的API在几分钟之内即可对任何应用程序中的用户进行身份验证&#xff0c;管理和保护。 今天尝试Okta。 当今的用户希望可以通过其计算机&#xff0c;手机&#xff0c;平板电脑或任何其他设备访问您的应用程序&#xff01; …

background复合属性顺序_CSS有哪些好用的字体属性?

本文创建于2020年9月&#xff0c;以下为正文&#xff1a;CSS中有哪些字体属性呢&#xff1f;font&#xff1a;复合属性。设置或检索对象中的文本特征。font-style&#xff1a;设置或检索对象中的字体样式。用于定义字体的风格&#xff0c;如&#xff1a;斜体&#xff08;italic…