Java 8——Lambda表达式
本篇文章不介绍Lambda的前世今生,这里只对Lambda表达的应用做详细了解。以及与内部类的差异点。
Lambda表达式
Lambda表达式是Java SE 8版本中引入的新的语法糖。将功能看做方法参数,将代码看做数据。
Lambda表达式语法:
LambdaParameters -> LambdaBody
Lambda表达式分为三部分:
- 参数列表
- ->符号
- 函数体
如:
() -> {} // 无参,返回结果为空
(x) -> System.out.println(x); // 带有一个参数
(Thread t) -> { t.start(); } // 带有一个申明参数
(int x, int y) -> x + y; // 带有两个申明参数,一个方法参数;
(int x, int y) -> return x +y; // 带有两个申明参数,一个方法参数;
(x, y) -> return x +y; // 带有两个申明参数,一个方法参数;
总体上表现如上形式,是Java中一种新的风格的表达式,和普通的表达的确有很大风格上的差异性。
这种风格的语法优势:
语法特点决定了语句的简洁紧凑,通过减少申明类型、return、单行语句去括号等等从而变得更精简;
具有更强的表达能力,减少冗余的代码,从而更关注真正的功能语句,语义更精确清晰;
函数式接口
已经对lambda表达式定义好了,但是如何在兼容面向对象的Java体系中使用。在面向对象体系中,一切皆是对象,怎样将这种表达式作为对象去使用,从而引入函数使接口:只有一个抽象方法的接口,代表着单功能的契约。
为了区分函数式接口和只包含一个抽象方法的普通接口,需要使用@FunctionalInterface注解标注接口,这样编译器就能将其作为函数式接口处理。
注:无论是本身具有还是继承都可以。如果继承父接口的抽象方法,也算入函数式接口一个抽象方法的统计中;如果覆盖Object类的方法,不会算入统计中,因为任何对象都继承自Object
有了函数式接口就可以很方便的使用lambda表达式,使用Java来进行函数式编程。
Function<String, String> f = (String x) -> x.toUpperCase();
f.apply("msg");
lambda表达式可以赋值给函数式接口,这里涉及到目标类型上下文,编译器根据lambda表达式所在的上下文推导其目标类型为Function。
List<String> list = new ArrayList<>();
list.forEach((x) -> System.out.println(x));
lambda表达式作为方法参数,其实是list.forEach方法中的方法参数是函数式接口,编译器推导lambda表达式类型为forEach中的函数式接口类型作为lambda表达式的目标类型。
从以上可以看出:
lambda表达式的目标类型必须是函数式接口,但是函数式接口和lambda表达式是两部分,函数式接口并不属于lambda表达式一部分,只是作为其目标类型;
函数式接口的抽象方法参数必须与lambda表达式的相一致:数量和个数;
函数式接口抽象方法返回参数与lambda表达式返回值一致:类型;
lambda表达式中抛出的受检异常与函数式接口抽象方法上的throws保持一致;
函数式接口使得lambda表达式能够更好的使用。Java是面向对象,如果在此基础上引入lambda,势必需要向前兼容:
如果引入新的类型,势必要与旧的api形成两套体系,这样就无法在历史版本中使用lambda表达式;
如果引入新的类型,Java类库需要对于同一功能就需要维护两份:过去历史版本/lambda版本;
如果使用已有的接口表示:
接口是 Java 类型系统的一部分
接口天然就拥有其运行时表示(Runtime representation);
基于这些原因,选择已有的接口类型作为函数式接口,然后引入lambda表达式是最折中平衡的方式。
Lambda表达式与匿名内部类
lambda表达式的简洁、紧凑的语法结构是匿名内部类所不能比拟的;
lambda表达式具有更明确的语义——因为只关注有效的代码;
lambda表达式的作用域比匿名内部类更加有友好(词法作用域/新的内部作用域):this在lambda表达式中表示外部内,而在内部类中表示当前内部类实例;变量名在lambda表达式中就是表示外部的,而在内部类中要防止继承自超类———lambda的词法作用域;(Shadowing问题,如果对Shadowing不熟悉,赶紧戮Shadowing)
lambda是函数式编程的体现,内部类任然是在面向对象层面;
参考
深入理解Java 8 Lambda(语言篇——lambda,方法引用,目标类型和默认方法)
The Java® Language Specification
Java 8——Lambda表达式的更多相关文章
- Java 8 Lambda表达式
Java 8 Lambda表达式探险 http://www.cnblogs.com/feichexia/archive/2012/11/15/Java8_LambdaExpression.html 为 ...
- 深入浅出 Java 8 Lambda 表达式
摘要:此篇文章主要介绍 Java8 Lambda 表达式产生的背景和用法,以及 Lambda 表达式与匿名类的不同等.本文系 OneAPM 工程师编译整理. Java 是一流的面向对象语言,除了部分简 ...
- Java 8 Lambda表达式10个示例【存】
PS:不能完全参考文章的代码,请参考这个文件http://files.cnblogs.com/files/AIThink/Test01.zip 在Java 8之前,如果想将行为传入函数,仅有的选择就是 ...
- Java 8 Lambda 表达式
Lambda 是啥玩意 简单来说,Lambda 就是一个匿名的方法,就这样,没啥特别的.它采用一种非常简洁的方式来定义方法.当你想传递可复用的方法片段时,匿名方法非常有用.例如,将一个方法传递给另外一 ...
- Java 8 lambda表达式示例
例1.用lambda表达式实现Runnable 我开始使用Java 8时,首先做的就是使用lambda表达式替换匿名类,而实现Runnable接口是匿名类的最好示例.看一下Java 8之前的runna ...
- Java 8 Lambda 表达式详解
一.Java 8 Lambda 表达式了解 参考:Java 8 Lambda 表达式 | 菜鸟教程 1.1 介绍: Lambda 表达式,也可称为闭包,是推动 Java 8 发布的最重要新特性. La ...
- 用Java 8 Lambda表达式实现设计模式:命令模式
在这篇博客里,我将说明如何在使用 Java 8 Lambda表达式 的函数式编程方式 时实现 命令 设计模式 .命令模式的目标是将请求封装成一个对象,从对客户端的不同类型请求,例如队列或日志请求参数化 ...
- Java基础学习总结(44)——10个Java 8 Lambda表达式经典示例
Java 8 刚于几周前发布,日期是2014年3月18日,这次开创性的发布在Java社区引发了不少讨论,并让大家感到激动.特性之一便是随同发布的lambda表达式,它将允许我们将行为传到函数里.在Ja ...
- 02、Java的lambda表达式和JavaScript的箭头函数
前言 在JDK8和ES6的语言发展中,在Java的lambda表达式和JavaScript的箭头函数这两者有着千丝万缕的联系:本次试图通过这篇文章弄懂上面的两个"语法糖". 简介 ...
- Java 8 Lambda表达式学习和理解
Java 8 Lambda表达式和理解 说明:部分资料来源于网络 时间:20190704 Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性.Lambda 允许把函数作为一 ...
随机推荐
- MEDICI仿真NMOS器件晶体管语法笔记
MEDICI仿真NMOS器件晶体管 TITLE TMA MEDICI Example 1 - 1.5 Micron N-Channel MOSFET 给本例子取的标题,对实际的模拟无用 COM ...
- TP5.0整合webuploader实现多图片上传功能
在https://github.com/fex-team/webuploader 下载webuploader并解压,解压后放到public里面.其中我把解压缩后的文件夹改名为webuploader,放 ...
- alpine基础镜像使用
关于Alpine的相关知识,可以参考下边的链接 https://yeasy.gitbooks.io/docker_practice/content/cases/os/alpine.html 一. al ...
- Linux shell if条件判断2
前面介绍linux shell的if判断的语法,现在再补充一点. Linux shell if条件判断1 分支判断结构 if , case 下面两个结构语法,已经在前面有过示例. 结构1: ...
- 系统管理员必须知道的PHP安全实践
Apache web 服务器提供了这种便利 :通过 HTTP 或 HTTPS 协议,访问文件和内容.配置不当的服务器端脚本语言会带来各种各样的问题.所以,使用 PHP 时要小心.以下是 25 个 PH ...
- Linux权限设置基础
chmod linux系统中文件或目录有两个属性:访问权限和文件所有者,简称“权限”和“归属”. 访问权限包括:读取.写入.可执行. 归属包括:属主(拥有该文件的用户).属组(拥有该文件的用户组) ...
- Websocket --socket.io的用法
<!DOCTYPE html> <html> <head> <title>Hello WebSocket</title> <link ...
- nginx 设置反向代理
一.多个路径指向同一ip的不同服务 参考地址:https://www.cnblogs.com/hanmk/p/9289069.html 编辑nginx.conf配置文件,新增加一个server模块,或 ...
- OpenCV 学习笔记(16)open创建无边框的显示窗口
https://blog.csdn.net/weixin_41794771/article/details/93198098 讲解地址 // 1获取窗口句柄 winName 窗口名字 HWND win ...
- (9-4 )deepsort在ubuntu1604下配置
Deep Sort with PyTorch YOLO https://github.com/ZQPei/deep_sort_pytorch 查看python版本 python3 --version ...