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,一经查实,立即删除!

相关文章

计算机电源稳压,一种用于计算机的电源稳压电路

主权项&#xff1a;1.一种用于计算机的电源稳压电路&#xff0c;其特征在于&#xff1a;包括变压器、桥式整流器、第一电容至第三电容、第一电阻至第五电阻、第一电位器、第二电位器、第一场效应管、第二场效应管、三极管和基准电压源&#xff0c;电压输入的两端分别与所述变压…

python输入代码如何清除_Bug清除手册-代码书写规范与基本使用(Python)

第 0-3 关 &#xf0024; 代码书写规范与基本使用 &#xf0024; Q &#xff1a;代码“” ( 等号 ) 的两边要不要空格&#xff0c;有影响吗&#xff1f; &#xf0021; A &#xff1a;没有影响&#xff0c;要习惯空格&#xff0c;这样更加规范美观&#xff0c;有辨识度&#xf…

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;反而让人不知道…

码云上传代码添加标签_第一次使用Git Bash Here 将本地代码上传到码云

当我们安装成功git工具时候&#xff0c;初次使用Git时&#xff0c;需要Git进行配置。1.点击桌面上的这个图标&#xff0c;打开Git Bash&#xff1a;如图所示2.配置自己的用户名和邮箱git config --global user.name "你的名字或昵称"git config --global user.email …

python执行adb命令_Python实现对adb命令封装

我就废话不多说了&#xff0c;大家还是直接看代码吧&#xff01; #!/usr/bin/evn python # -*- coding:utf-8 -*- # FileName adbtools.py # Author: HeyNiu # Created Time: 2016/9/19 """ adb 工具类 """ import os import platform import re…

ubuntu优化服务器网络连接数,ubuntu下解决高并发socket最大连接数限制,tcp默认1024个连接...

linux系统默认ulimit为1024个访问 用户最多可开启的程序数目。一般一个端口(即一个进程)的最高连接为2的16次方65536通过这个命令 ulimit -n 可以看到默认值为1024查看全局文件句柄数限制(系统支持的最大值)cat /proc/sys/fs/file-max查看每个进程文件句柄数限制ulimit -n第一步…

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

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

在AWS第1部分中使用Terraform自动缩放组:基本步骤

因此&#xff0c;您想使用Terraform在AWS上创建一个自动缩放组。 以下是达到此目的的最少步骤。 在编写实际代码之前&#xff0c;应指定aws terraform提供程序以及provider.tf文件上的区域。 provider "aws" { version "~> 2.0" region "eu-wes…

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…

虚拟空间独立服务器哪个好,共享虚拟主机和独立哪个好

共享虚拟主机和独立哪个好&#xff1f;现在市面上的虚拟主机产品分为共享主机和独立虚拟主机&#xff0c;那对于用户来说&#xff0c;他们二者之间哪个更好些呢。共享虚拟主机共享虚拟主机指多个用户共同平均使用同一台服务器资源&#xff0c;包括CPU、内存、带宽、硬盘和IP都是…

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

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

pandas用众数填充缺失值_7步搞定数据清洗-Python数据清洗指南

脏数据就是在物理上临时存在过&#xff0c;但在逻辑上不存在的数据。数据清洗是整个数据分析过程的第一步&#xff0c;就像做一道菜之前需要先择菜洗菜一样。数据分析师经常需要花费大量的时间来清洗数据或者转换格式&#xff0c;这个工作甚至会占整个数据分析流程的80%左右的时…

有盘和无盘服务器,网吧系统的终极解决之道:无盘系统+有盘(转)

1、效果好&#xff1a;系统启动飞速&#xff0c;玩大型游戏飞速&#xff0c;不会丢失账号&#xff0c;系统永远干净。2、不会中毒&#xff1a;系统文件从服务器上的镜像中读取&#xff0c;大型游戏从本地硬盘读取&#xff0c;本地硬盘全盘还原&#xff0c;游戏穿透更新。3、投资…

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

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

微信分享 ajax冲突,微信jssdk分享功能开发及解决ajax跨域的问题

微信JS-SDK说明文档微信JS-SDK Demo我所要实现的分享功能要求&#xff1a;只要提供一段js代码给前端美工放置在静态页面等就可以实现分享功能。js代码如下&#xff1a;urllocation.href;$.ajax({type : "get",url : "http://域名/wx/test/jssdk.php?url"u…

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

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

合肥工业大学机器人技术期末_机器人技术第三次作业(HFUT)

第三次作业本人代码水平十分有限&#xff0c;仅供参考&#xff0c;有错误请指出java源码&#xff1a;package robathomework3;import java.lang.Math;//点类class point {double x 0;double y 0;point(double x, double y) {this.x x;this.y y;}void print() {System.out.p…