02、Java的lambda表达式和JavaScript的箭头函数
前言
在JDK8和ES6的语言发展中,在Java的lambda表达式和JavaScript的箭头函数这两者有着千丝万缕的联系;本次试图通过这篇文章弄懂上面的两个“语法糖”。
简介
Lambda 表达式来源于 C# 5.0,但又不太确定,于是查了下 百度百科:Lambda表达式,仍然没有得到明确的答案,所以懒得去纠结这个问题了。
箭头函数(arrow function),就是C#中的lambda表达式,据说Java8也把它加入了。但不管怎样,JS正在从其它语言吸纳优秀的特性(比如yield, class, 默认参数等等),且不论这些特性好坏,这件事本身就是极好的(至少我们正在使用的是一个充满活力的工具)
只是Java用->
箭头,C#用的箭头与JS一样:=>
,这个箭头叫“lambda运算符”,行话读作”goes to”
lambda表达式(箭头函数)据说是定义函数最简洁的方法,语法上几乎没有冗余成分了。因为JS弱类型的特点,JS中的lambda表达式要比C#和Java中的更简洁(少了参数类型声明)
一句话,箭头函数就是lambda表达式,提供了更简洁的function定义方式
lambda语法
什么是lambda?
这里先给简要的定义:将匿名函数复制给变量的简写方式的函数称为 lambda 表达式。
1、java的场景中:把“一块代码”赋给一个Java变量
这个是简化过程:
2、JS中同理也是比较简单的
var fun1 = funcation(int x,int y){
return (x+y);
}
简写如下:
var fun1 = (x,y)=>x+y;
lambda的语法定义
这里由于Java一切皆对象的原因,暂时先介绍JavaScript的定义,但Java基本雷同
JavaScript的箭头函数
Lambda 表达式的主要形式是如下定义,符号的左侧是参数,右侧是表达式或语句块。
(参数列表) => { 语句块 }
当“语句块”只有一条语句的时候,可以省略大括号,就成了
(参数列表) => 语句
注意: Lambda 表达式一般是作为参数或者值使用,所以根据使用的上下文,大部分情况下编译器可以推断出 Lambda 表达式的参数类型;Lambda 表达式的参数通常是省略类型的
Java的lambda表达式
Lambda 表达式的作用其实就是匿名方法,而 Java 中并没有匿名方法这一语法。不过 Java 中有匿名对象,当你直接 new 一个接口并实现接口方法的时候,Java 编译器实际是产生了一个类(匿名类)来实现这个接口,然后再返回这个类的一个实例,也就是匿名对象;Lambda表达式本身就是一个接口的实现。
这种只有一个接口函数需要被实现的接口类型,我们叫它”函数式接口“。为了避免后来的人在这个接口中增加接口函数导致其有多个接口函数需要被实现,变成"非函数接口”,我们可以在这个上面加上一个声明@FunctionalInterface, 这样别人就无法在里面添加新的接口函数了:
下面是一个完整的案例:
@FunctionalInterface
public interface WorkerInterface {
public void doSomeWork();
}
public class WorkerInterfaceTest {
public static void execute(WorkerInterface worker) {
worker.doSomeWork();
}
public static void main(String [] args) {
//invoke doSomeWork using Annonymous class
execute(new WorkerInterface() {
@Override
public void doSomeWork() {
System.out.println("Worker invoked using Anonymous class");
}
});
//invoke doSomeWork using Lambda expression
execute( () -> System.out.println("Worker invoked using Lambda expression") );
}
}
lambda的常见使用场景
上面通过两个简单的案例演示了lambda,现在总结一下在Java和JavaScript常见的用法和使用常见。
java中常见的使用场景
1. 何时用?
JAVA8中就提供了这种“函数式编程”的方法 —— lambda表达式,供我们来更加简明扼要的实现内部匿名类的功能。
函数式接口:Functional Interface.
定义的一个接口,接口里面必须 有且只有一个抽象方法 ,这样的接口就成为函数式接口。
在可以使用lambda表达式的地方,方法声明时必须包含一个函数式的接口。
简单的说,凡是(java8以上)函数式接口都可以尽量使用lambda表达式,注意:如果我们提供的这个接口包含一个以上的Abstract Method,那么使用lambda表达式则会报错。建议定义的接口加上@FunctionalInterface
注解。
2. 怎么用?
根据之前的思路;只要找到Java中函数式接口的皆可以放出lambda表达式
的大招。
JDK 8之前已有的函数式接口
java.lang.Runnable
java.util.concurrent.Callable
java.security.PrivilegedAction
java.util.Comparator
java.io.FileFilter
java.nio.file.PathMatcher
java.lang.reflect.InvocationHandler
java.beans.PropertyChangeListener
java.awt.event.ActionListener
javax.swing.event.ChangeListenerJava SE 8中增加了一个新的包:java.util.function,它里面包含了常用的函数式接口:
补充: 关于函数式接口的详细总结
1)Java8中Iterable的foreach(Comsumer action)的函数式接口
2)Java8中Iteror的forEachRemaining(Comsumer action)的函数式接口
3)Java8中函数式接口Predicate;Collections的removeIf(Predicate filter)
...其实还有很多,就不一一列举了,其实根据规则就很容易了加上编译器优化,其实写出lambda其实也是很容易。
JavaScript的箭头函数常用场景:
由于JavaScript基于函数编程,lambda表达式非常灵活常用,基本上对于参数的简单操作都可以使用箭头函数完成,这里可以告诉你不要试图滥用。
- 箭头函数适合于无复杂逻辑或者无副作用的纯函数场景下,例如用在map、reduce、filter的回调函数定义中;
- 不要在最外层定义箭头函数,因为在函数内部操作this会很容易污染全局作用域。最起码在箭头函数外部包一层普通函数,将this控制在可见的范围内;
- 如开头所述,箭头函数最吸引人的地方是简洁。在有多层函数嵌套的情况下,箭头函数的简洁性并没有很大的提升,反而影响了函数的作用范围的识别度,这种情况不建议使用箭头函数。
参考资料
02、Java的lambda表达式和JavaScript的箭头函数的更多相关文章
- 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表达式示例
例1.用lambda表达式实现Runnable 我开始使用Java 8时,首先做的就是使用lambda表达式替换匿名类,而实现Runnable接口是匿名类的最好示例.看一下Java 8之前的runna ...
- 转载:深入浅出 Java 8 Lambda 表达式
原文地址:http://viralpatel.net/blogs/Lambda-expressions-java-tutorial/ OneAPM for Java 能够深入到所有 Java 应用内部 ...
- Java 8 Lambda表达式10个示例【存】
PS:不能完全参考文章的代码,请参考这个文件http://files.cnblogs.com/files/AIThink/Test01.zip 在Java 8之前,如果想将行为传入函数,仅有的选择就是 ...
- 掌握 Java 8 Lambda 表达式
Lambda 表达式 是 Java8 中最重要的功能之一.使用 Lambda 表达式 可以替代只有一个函数的接口实现,告别匿名内部类,代码看起来更简洁易懂.Lambda 表达式 同时还提升了对 集合 ...
- Java 8 Lambda 表达式
Lambda 是啥玩意 简单来说,Lambda 就是一个匿名的方法,就这样,没啥特别的.它采用一种非常简洁的方式来定义方法.当你想传递可复用的方法片段时,匿名方法非常有用.例如,将一个方法传递给另外一 ...
- Java 8 Lambda 表达式详解
一.Java 8 Lambda 表达式了解 参考:Java 8 Lambda 表达式 | 菜鸟教程 1.1 介绍: Lambda 表达式,也可称为闭包,是推动 Java 8 发布的最重要新特性. La ...
- 用Java 8 Lambda表达式实现设计模式:命令模式
在这篇博客里,我将说明如何在使用 Java 8 Lambda表达式 的函数式编程方式 时实现 命令 设计模式 .命令模式的目标是将请求封装成一个对象,从对客户端的不同类型请求,例如队列或日志请求参数化 ...
随机推荐
- HDU 1286:找新朋友(欧拉函数)
http://acm.hdu.edu.cn/showproblem.php?pid=1286 题意:中文. 思路:求欧拉函数. #include <cstdio> #include < ...
- 1.Solr安装与配置
1.Solr安装 1:安装 Tomcat,解压缩即可. 2:解压 solr. 3:把 solr 下的dist目录solr-4.10.3.war部署到 Tomcat\webapps下(去掉版本号). 4 ...
- 并发编程之美,带你深入理解java多线程原理
1.什么是多线程? 多线程是为了使得多个线程并行的工作以完成多项任务,以提高系统的效率.线程是在同一时间需要完成多项任务的时候被实现的. 2.了解多线程 了解多线程之前我们先搞清楚几个重要的概念! 如 ...
- 自我救赎 → 利用 IDEA 和 Spring Boot 搭建 SSM
前言 开心一刻 儿子读高中放学回来了,一向不管他学习的我突然来了兴趣,想看看他的学习他的状况,抄起他的数学习题看了起来,当看到 1 x 2 x 3 x 4 x 5 x 6 x 7 x 8 x 9 x ...
- Bzoj 3170[Tjoi 2013]松鼠聚会 曼哈顿距离与切比雪夫距离
3170: [Tjoi 2013]松鼠聚会 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1318 Solved: 664[Submit][Stat ...
- 开设“C程序答疑解惑”的初衷
博主经常在QQ群里.论坛里看到好多C语言初学者,甚至是有一定编程经验的人,咨询在编程中遇到的一些稀奇古怪的问题.博主对这些问题做过分析汇总,有些问题确实隐蔽的非常深,像break关键字用的不对啦,局部 ...
- android_alertDialog
主文件 package cn.com.sxp;import android.app.Activity;import android.app.AlertDialog;import android.con ...
- Java编程思想:内部类其他知识点
public class Test { public static void main(String[] args) { // InheritInner.test(); // EggTest.test ...
- python 的深浅拷贝问题
深浅拷贝概念 基本类型和引用类型数据拷贝的问题.因为基本类型的数据大小是固定的,所以他保存在栈内存中:而引用类型的数据大小不固定,因而保存在堆内存中,单引用类型在栈内存中只保存一个指向堆内存的指针. ...
- 算法学习笔记,几个简单的Demo
算法初学的一些心得 前言:现在工作也快一年多了,有时间下班回家会学学算法,陆陆续续也接触了一些 貌似我知道的就冒泡排序其他的都不是很了解 最近买了一本书,边学边记录吧! 一些常用的方法 暴力破解 下面 ...