用20分钟的时间,再来了解下 Lambda 表达式。为什么要学习 Lambda 表达式呢?毕竟现在的 Android 使用的 JDK 版本官方并不支持 Lambda。这里列出了一些需要理由,来说明为什么要学习 Lambda 表达式。

Lambda 表达式在后续的 Android 版本中必将得到官方支持,一些其他的 Android 开发语言例如 kotlin,未雨绸缪总是好事。

Java8 实现的 Lambda 表达式,有助于我们更好地理解编程中非常重要的几个概念,尤其是 闭包,理解数据和函数的等价性。

使用 Lambda 能够简化我们的代码,是很甜的语法糖,让我们能更好地专注于实现逻辑。

Android N 将官方支持 Lambda!

背景介绍

也许你听过 Execution in the Kingdom of Nouns, 中文翻译也叫 名词王国里的死刑,这是很有意思的一篇文章,找了一个翻译的链接,没有读过的同学可以看看, 名词王国里的死刑(翻译) - Hi!Roy!。在编写 Java 程序的时候,我们会使用类似于 ViewHelper,Compartor 等等这样的名词,几乎所有的类都是名词,Java 世界里面名词是一等公民,而动词是二等公民。但在另一些编程范式里面,名词和动词是具有同等地位的 ,代表就是函数式编程。在这些更纯粹的编程语言中,函数同样也是数据,可以像数据一样被传递,被消费,有兴趣的同学可以看看 高阶函数。引入 Lambda 是Java 对这种情况的小弥补。

闭包是函数式编程中非常重要的概念,个人对闭包这个概念的理解是,能够访问上下文环境,自包含的函数代码块,可以在代码中被传递和试用。Java 的匿名函数一定上可以实现闭包,但有了 Lambda 表达式后可以实现得更加简洁有力。

久而久之,对 Lambda 的呼声越来越高,因此在 Java8 时,官方就推出了 Lambda 表达式。

语法简介

形如 (arguments) -> (body) 的,就是 Lambda 表达式。我们来看看一些简单的例子。

[代码]java代码:(int a,int b) -> {return a + b; } () -> System.out.println("Hello World"); (String s) -> { System.out.println(s); } () ->42 () -> {return 3.1415 };

Lambda 表达式可以有0个,1个以及多个参数。

参数的类型可以显示声明,也可以通过类型推导(通过上下文环境推导出)得出。

参数用括号包含,多个参数用逗号分隔。

空括号表示无参数。

如果是单个参数,同时类型可推导时,可以是不用括号包含起来。

body 部分,可以有 0 行,或者多行

当 body 部分只有一行,且返回类型匹配时,可以不加大括号。

当 body 部分有多行时,则必须用大括号包起来,也就是代码块。

总结地说,Lambda 表达式在语法上就是匿名函数的一种简写方式。

函数式接口

也许你会好奇,这些语法糖是怎么实现的?就没有一点点要求吗?我们知道 Runnable 是可以用于函数式表达式的,在查看 JDK 文档时,发现了这样的一条注释。

This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference.

注释里面提及了 functional interface,Lambda 表达式规定必须是函数式接口。在 java8 中用 @FunctionalInterface 这个注解来表示是函数式接口,这里注意的是,函数式接口必须只能有申明一个抽象方法,如果有大于一个的情况,那么会发生编译错误。

我们以 Runnable 为例子,看看新的 Lambda 表达式怎么用。

[代码]java代码://Old way:new Thread(new Runnable() {@Overridepublic void run() {System.out.println("Old!");}}).start(); //New way:new Thread(() -> System.out.println("New")).start();

空小括号表示没有参数,而代码块只有一块,return 的是 void,所以也可以去掉大括号。

在 java 7 中,已经是函数式接口的有.java.lang.Runnable

java.util.concurrent.Callable

java.security.PrivilegedAction

java.util.Comparator

java.io.FileFilter

java.beans.PropertyChangeListener

此外 java8 还增加了一个包,用来包含其他常用的函数式接口。

Predicate -- a boolean-valued property of an object

Consumer -- an action to be performed on an object

Function – a function transforming a T to a R

Supplier -- provide an instance of a T (such as a factory)

UnaryOperator -- a function from T to T

BinaryOperator -- a function from (T, T) to T

我们来看下面这个例子,Java 会通过编译器,来推导具体是什么类型,即使是泛型的情况。

[代码]java代码:1Callable c = () -> “done”;

词法作用域

Lambda表达式不会从超类中继承任何变量名,也不会引入一个新的作用域。Lambda表达式基于词法作用域,也就是说lambda表达式函数体里面的变量和它外部环境的变量具有相同的语义。例如,我们在 Lambda 外部声明了一个变量,在 Lambda 内部可以直接使用。大家在使用匿名函数的时候,会发现出于线程安全的目的,外部传入的变量必须为 final 的,而 Lambda 并不要求你也同样声明 final,但是在之后不能修改该值。这个概念被称为变量捕获。

在 Lambda 中的this,同样因为词法作用域的问题,指得是创建 Lambda 表达式所有的地方的 this。

Android 开发中该如何使用 Lambda

由于 Android Rom 使用的 Java Class 版本还是 6,7 的版本,在 Android 中使用 Lambda,需要对 Java 8 做一些桥接处理,以作适配的需要。这里可以使用 gradle-retrolambda 这个库,就能很方便地使用 Lambda 了。

下载并安装 Java 8

在 gradle 文件中,加入以下代码。

[代码]xml代码:buildscript {repositories {mavenCentral()}dependencies {classpath 'me.tatarka:gradle-retrolambda:3.4.0'}}// Required because retrolambda is on maven centralrepositories {mavenCentral()}apply plugin: 'com.android.application' //or apply plugin: 'java'apply plugin: 'me.tatarka.retrolambda'

Android编译Lambda,Android lambda 入门教程相关推荐

  1. ogre android 编译,Ogre3d Android平台编译教程

    上一篇我们讲了Ogre3d 在 Window平台的编译流程方法 这一篇我们介绍 Ogre3d 编译到Android 平台的方法.可以和官方英文教程对照学习. 转载自博客 http://blog.csd ...

  2. 全志 android 编译,全志Android SDK编译详解(二)

    注意要确定安装了jdk) 第一步: cd  lichee; ./build.sh  -p sun5i_elite -k 3.0  (apt-get install uboot-mkimage需要安装m ...

  3. android 编译主机,Android】源码编译 ---zzz

    问题解决 参考 1)/bin/bash: prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi-gcc: 权限不够 解决:chmod a+x ...

  4. H6机顶盒Android编译[2]-Android编译

    注意:本人也是第一次android编译,记录其过程为方便自己,同时给初学者提供参考,不正确之处还望包含指正! 前言 使用易新泰的H6机顶盒平台,搭载全志H6处理器,使用易新泰提供的SDK环境,使用ub ...

  5. android 编译mupdf,Android mupdf在Ubuntu下的编译教程(最详细的教程)

    mupdf是一个国外的打开pdf的开源框架,就不多做介绍了,直接入正题. 一.Ubuntu的安装(网上很多教程) 二.Ubuntu下安装ndk环境(网上很多教程) 三.mupdf的源码获取方式: 1. ...

  6. Android数据库新王者-Realm入门教程

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u010046908/article/details/51629262 好长时间没有写关于Androi ...

  7. android dbflow教程,Android高性能ORM数据库DBFlow入门教程

    一.引入依赖.初始化 需要引入apt和maven,配置项目的 build.gradle buildscript { repositories { jcenter() } dependencies { ...

  8. Java 8 Lambda表达式官方入门教程(包括Lambda表达式介绍和语法)

    Java8做出了比较大的更新,支持了很多新特性,Java8引入的Lambda表达式这一特性,使Java8支持函数式编程,目前网上有较多的教程,本文整理了来自Oralce官方提供的教程. Lambda表 ...

  9. android studio 安卓制作app入门教程,Android开发:AndroidStudio安卓APP入门教程

    轻松学会Android,让工作主动找你 即使你是零基础,也能掌握真正的技术 低风险.低投入,随时随地学习 全方位的技术支持:高清视频.源码.资料.技术指导 课程目录 章节1:初识篇 课时1开发环境搭建 ...

  10. android 新的布局,Android新布局方式ConstraintLayout快速入门教程

    前言 在android开发中,我们通常是手写布局,很少会用拖动来写布局,虽然constraintlayout在i/o上以拖动来展现了各种功能,我估计在以后开发中,程序员还是习惯手撸代码. 我自己试着拖 ...

最新文章

  1. 30个Python常用极简代码,拿走就用
  2. 一个关于小程序Iot的具体实现(MQTT版)
  3. iis、apache与nginx禁止目录执行asp、php脚本的实现方法
  4. 目标意识应求成大于避败 思考时不要先意识到身不足而自我设限
  5. Ubuntu 18.x 环境下mysql创建用户并更改用户权限
  6. 5.触摸touch,单点触摸,多点触摸,触摸优先和触摸事件的吞噬
  7. GitHub政府用户破万:开源成重塑政府新手段
  8. hadoop没有datanode_Hadoop运行在Kubernetes平台实践
  9. 【转】Oracle 系统权限详细列表
  10. python识别复杂验证码2020_Python识别验证码!学会这步,百分之60的网站你基本都能识别了!...
  11. php运行方式isapi,在IIS6中配置PHP运行(ISAPI模式)环境(1)
  12. DeepFaceLab 2 merge阶段参数
  13. 微信小程序学习14--小程序微信支付流程分析及实现
  14. mdf数据库文件怎么打开?
  15. Android sdk platform,sdk tools,sdk Build tools,sdk platform tools 的关系
  16. python机械臂坐标变换——实现机械臂末端相对移动
  17. 雨阳打字通 v1.0 发布
  18. C/S与B/S应用的区别
  19. android 调用系统铃声方法
  20. matlab填充封闭包含区域,求指导matlab怎么填充曲线构成的封闭区域

热门文章

  1. Android之原始的QQ好友分组实现
  2. python 环境配置
  3. macbook开机密码输入正确,却提示“密码错误”无法登陆解决办法
  4. 故事要从我白嫖了一个阿里云服务器说起
  5. 下载不了代码仓库的代码怎么办?
  6. 手机翻书效果html,移动端实现翻书效果
  7. Impala时间转换to_date、to_timestamp
  8. 绿茶集团在港上市申请再失效:王勤松夫妇为实控人,翻台率不及格
  9. 移植python到小米路由器记录。
  10. 基因家族分析⑦:用MEME查询基因家族的motif