本篇文章不介绍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. django环境搭建(基于anaconda环境)

    环境:win7,anaconda,python3.5 1.介绍 Django特点:具有完整的封装,开发者可以高效率的开发项目,Django将大部分的功能进行了封装,开发者只需要调用即可,如此,大大的缩 ...

  2. 部署LNMP应用平台

    一.LNMP应用平台概述 1.概述:LNMP代表的就是:Linux系统下Nginx+MySQL+PHP这种网站服务器架构.Nginx是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/ ...

  3. 【转】Pandas学习笔记(二)选择数据

    Pandas学习笔记系列: Pandas学习笔记(一)基本介绍 Pandas学习笔记(二)选择数据 Pandas学习笔记(三)修改&添加值 Pandas学习笔记(四)处理丢失值 Pandas学 ...

  4. 2019年南京网络赛E题K Sum(莫比乌斯反演+杜教筛+欧拉降幂)

    目录 题目链接 思路 代码 题目链接 传送门 思路 首先我们将原式化简: \[ \begin{aligned} &\sum\limits_{l_1=1}^{n}\sum\limits_{l_2 ...

  5. Springboot JackSon

    1. SpringBoot JSON工具包默认是Jackson,只需要引入spring-boot-starter-web依赖包,自动引入相应依赖包: <dependency> <gr ...

  6. Google Chrome 解决 “您的连接不是私密连接” 和被毒霸劫持

    一.解决 “您的连接不是私密连接” 前一段时间,Chrome 突然显示出了“您的连接不是私密连接”,这下可难受了,大部分的网站打开都有问题. 找了各种方法,各种设置都是不行. 一.暴力.费力的方法直接 ...

  7. 5.服务注册与发现Consul,简学API,手动注册和删除服务

    package main import ( httptransport "github.com/go-kit/kit/transport/http" mymux "git ...

  8. three.js 设置透明度

    原文:https://www.cnblogs.com/amy2011/p/6148736.html 材质: 材质就像物体的皮肤,决定了几何体的外表,例如是否像草地/金属,是否透明,是否显示线框等 Th ...

  9. 三天精通Vue--ES6的常用语法

    详细学习请参考  阮一峰的ECMAScript 6 入门 let和const的使⽤ es5中使用var来声明全局变量 es5中我们学习了使用var来声明变量,但是使用var声明变量,会存在变量提升的问 ...

  10. 三天精通Vue--学前摘要

    Vue Vue是一个前端框架,中文学习教程https://cn.vuejs.org/v2/guide/components.html 学习的前提:一点的 HTML+CSS+js node.js是前端的 ...