本篇文章不介绍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表达式与匿名内部类

  1. lambda表达式的简洁、紧凑的语法结构是匿名内部类所不能比拟的;

  2. lambda表达式具有更明确的语义——因为只关注有效的代码;

  3. lambda表达式的作用域比匿名内部类更加有友好(词法作用域/新的内部作用域):this在lambda表达式中表示外部内,而在内部类中表示当前内部类实例;变量名在lambda表达式中就是表示外部的,而在内部类中要防止继承自超类———lambda的词法作用域;(Shadowing问题,如果对Shadowing不熟悉,赶紧戮Shadowing)

  4. lambda是函数式编程的体现,内部类任然是在面向对象层面;

参考

深入理解Java 8 Lambda(语言篇——lambda,方法引用,目标类型和默认方法)

The Java® Language Specification

Lambda Expressions

Java 8——Lambda表达式的更多相关文章

  1. Java 8 Lambda表达式

    Java 8 Lambda表达式探险 http://www.cnblogs.com/feichexia/archive/2012/11/15/Java8_LambdaExpression.html 为 ...

  2. 深入浅出 Java 8 Lambda 表达式

    摘要:此篇文章主要介绍 Java8 Lambda 表达式产生的背景和用法,以及 Lambda 表达式与匿名类的不同等.本文系 OneAPM 工程师编译整理. Java 是一流的面向对象语言,除了部分简 ...

  3. Java 8 Lambda表达式10个示例【存】

    PS:不能完全参考文章的代码,请参考这个文件http://files.cnblogs.com/files/AIThink/Test01.zip 在Java 8之前,如果想将行为传入函数,仅有的选择就是 ...

  4. Java 8 Lambda 表达式

    Lambda 是啥玩意 简单来说,Lambda 就是一个匿名的方法,就这样,没啥特别的.它采用一种非常简洁的方式来定义方法.当你想传递可复用的方法片段时,匿名方法非常有用.例如,将一个方法传递给另外一 ...

  5. Java 8 lambda表达式示例

    例1.用lambda表达式实现Runnable 我开始使用Java 8时,首先做的就是使用lambda表达式替换匿名类,而实现Runnable接口是匿名类的最好示例.看一下Java 8之前的runna ...

  6. Java 8 Lambda 表达式详解

    一.Java 8 Lambda 表达式了解 参考:Java 8 Lambda 表达式 | 菜鸟教程 1.1 介绍: Lambda 表达式,也可称为闭包,是推动 Java 8 发布的最重要新特性. La ...

  7. 用Java 8 Lambda表达式实现设计模式:命令模式

    在这篇博客里,我将说明如何在使用 Java 8 Lambda表达式 的函数式编程方式 时实现 命令 设计模式 .命令模式的目标是将请求封装成一个对象,从对客户端的不同类型请求,例如队列或日志请求参数化 ...

  8. Java基础学习总结(44)——10个Java 8 Lambda表达式经典示例

    Java 8 刚于几周前发布,日期是2014年3月18日,这次开创性的发布在Java社区引发了不少讨论,并让大家感到激动.特性之一便是随同发布的lambda表达式,它将允许我们将行为传到函数里.在Ja ...

  9. 02、Java的lambda表达式和JavaScript的箭头函数

    前言 在JDK8和ES6的语言发展中,在Java的lambda表达式和JavaScript的箭头函数这两者有着千丝万缕的联系:本次试图通过这篇文章弄懂上面的两个"语法糖". 简介 ...

  10. Java 8 Lambda表达式学习和理解

    Java 8 Lambda表达式和理解 说明:部分资料来源于网络 时间:20190704 Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性.Lambda 允许把函数作为一 ...

随机推荐

  1. Prometheus(三):Prometheus监控交换机(snmp)

    默认已安装Prometheus服务,服务地址:192.168.56.200 一.获取交换机snmp信息 snmp服务IP(交换机IP):172.20.2.83 snmp community:dfete ...

  2. ubuntu18 安装坑点记录(华硕飞行堡垒)

    环境 电脑:华硕飞行堡垒FX53VD 显卡:集成显卡+NVIDIA显卡(linux版本很不友好) 镜像:ubuntu18.04.3 LTS 准备安装 * 制作启动盘(百度) * 设置U盘启动项:按F2 ...

  3. springboot常用方法手记

    1.Map方法 获取map的key和value的方法 Map<String, Object> map = new HashMap<>(); map.put("mobi ...

  4. matplotlib 自带的几种美化样式

    1.用 matplotlib.pyplot.style.avaliable 可查看 matplotlib 自带的美化样式如下: ['bmh', 'classic', 'dark_background' ...

  5. 剑指offer-08 二叉树的下一个节点

    剑指offer第8题,本来想找leetcode上对应的题,后来没找到,直接去牛客网上刷了. 题目描述: 给定一个二叉树和其中的一个结点(pNode),请找出中序遍历顺序的下一个结点并且返回.注意,树中 ...

  6. C#进阶系列 ---- 《CLR via C#》

      [C#进阶系列]30 学习总结 [C#进阶系列]29 混合线程同步构造 [C#进阶系列]28 基元线程同步构造 [C#进阶系列]27 I/O限制的异步操作 [C#进阶系列]26 计算限制的异步操作 ...

  7. 如何将MultipartFile转换成based4

    public String test(MultipartFile file) throws Exception{ BASE64Encoder base64Encoder =new BASE64Enco ...

  8. Spring AOP技术本质认识

    Spring AOP技术本质认识 一.AOP简介   AOP(Aspect Oriented Programming,面向切面编程),把某一类问题集中在一个地方进行处理,比如处理程序中的点击事件.打印 ...

  9. 第二阶段团队冲刺(个人)——One

    今天的任务:修改登录界面.将原有的登录界面全部改掉,仿照千图网,做界面.

  10. limits the number of elements in an IN predicate to 2100 entries.

    org.hibernate.engine.jdbc.spi.SqlExceptionHelper 131 - [TxId : f68db5f5b-qmgnc^1561639897640^271530 ...