一、lambda表达式的来源

Lambda 表达式(拉姆达表达式)来源于lambda演算是Alonzo Church给出的一套图灵机等价的形式计算系统。lambda演算系统以函数和变量为基础,也可以进行符号演算。Church希望用这套系统来表示有关数学的一切,比如说,用一系列函数来表达自然数。
“Lambda 表达式”是一个匿名函数,它可以包含表达式和语句,并且可用于创建委托或表达式树类型。lambda表达式是匿名函数,但是匿名函数不全是使用lambda表达式来写的。

二、编程语言中的lambda表达式和匿名函数
C#有lambda、匿名函数,js有匿名函数、闭包(Ruby之父松本行弘在《代码的未来》一书中解释:闭包就是把函数以及变量包起来,使得变量的生存周期延长),OC中有block,从功能性上说lambda和closure(或是OC中的blocks)是一个东西,只是不同语言的不同称呼罢了,它们都是匿名函数。若匿名函数捕获了一个外部变量,那么它就是一个closure。使用它们一般会有两个好处:简洁、捕获变量.
1.简洁
比如一个方法只在这一处使用,我们就没有必要创建方法然后调用,我们可以直接在其他函数内部声明定义,这样将来查找也不用去其他地方查找了也是比较方便的。例如OC中页面传值一般用代理或block,代理的话每次都要设置delagate,实现代理方法,创建的对象和代理方法分离,这样以后维护某个功能,就可能会忘记实现代理。
2.捕获变量
捕获变量在js中更能说明了。由于js中的作用域和其他语言的不一样.闭包其实就是函数的嵌套,内层的函数可以使用外层函数的所有变量,即使外层函数已经执行完毕。使用闭包减少对全局变量是使用.

三、Java中中的lambda表达式

由于Java是相对较为面向对象的语言,一个Java对象中可以包含属性和方法(函数),方法(函数)不能孤立于对象单独存在。这样就产生了一个问题,有时候需要把一个方法(函数)作为参数传到另外一个方法中的时候(比如回调功能),就需要创建一个包含这个方法的接口,传递的时候传递这个接口的实现类,一般是用匿名内部类的方式来。如下面代码,首先创建一个Runnable的接口,在构造Thread时,创建一个Runnable的匿名内部类作为参数:

Java代码 

等同于

Java代码 
  1. ;}

继续看更多的例子:

Java代码 
  1. (String s) -> { System.out.println(s); }

创建一个FileFilter,文件过滤器:

Java代码 
  1. FileFilter java = (File f) -> f.getName().endsWith(".java")

创建一个线程:

Java代码 
  1. new Thread(() -> {
  2. //do sth here...
  3. }).start()

创建一个Callable:

Java代码 
  1. Callable<String> c = () -> "done";

创建一个String的比较器:

Java代码 
  1. Comparator<String> c = (s1, s2) -> s1.compareToIgnoreCase(s2);

而且lambda表达式可以赋值给一个变量:

Java代码 
  1. Comparator<String> c;
  2. c = (String s1, String s2) -> s1.compareToIgnoreCase(s2);

还可以作为方法的返回值:

Java代码 
  1. public Runnable toDoLater() {
  2. return () -> {
  3. System.out.println("later");
  4. };
  5. }

从上面可以看到,一个lambda表达式被作为一个接口类型对待,具体对应哪个接口,编译器会根据上下文环境推断出来,如下面的lambda表达式就表示一个ActionListener.

Java代码 
  1. ActionListener l = (ActionEvent e) -> ui.dazzle(e.getModifiers());

这有可能会造成一个表达式在不同的上下文中被作为不同的类型,如下面的这种情况,尽管两个表达式是相同的,上面的表达式被推断为Callable的类型,下面的会被推断为PrivilegedAction类型。

Java代码 
  1. Callable<String> c = () -> "done";
  2. PrivilegedAction<String> a = () -> "done";

那么编译器是根据哪些因为决定一个表达式的类型呢?

如果一个表达式被推断为是T类型的,需要满足以下4个条件:

1.T是函数式接口类型(只声明唯一一个方法)

2.表达式和T中声明的方法的参数个数一致,参数类型也一致

3.表达式和T中声明的方法的返回值类型一致

4.表达式和T中声明的方法抛出的异常一致

JAVA8与lambda表达式的更多相关文章

  1. Java8中Lambda表达式的10个例子

    Java8中Lambda表达式的10个例子 例1 用Lambda表达式实现Runnable接口 //Before Java 8: new Thread(new Runnable() { @Overri ...

  2. java8的lambda表达式,将List<DTO> 转为 List<DO>

    将List<PhoneDTO>转为List<PhoneDO>,通过java8的lambda表达式来操作,比传统的for循环精简很多: /** * List<PhoneDT ...

  3. java8的lambda表达式

    关于java8的lambda表达式 lambda表达式一般用于接口,因为lambda表达式是函数式编程. 1.有且仅有一个抽象方法被称为函数式接口,函数式接口可以显示的被@FunctionalInte ...

  4. java8中lambda表达式的应用,以及一些泛型相关

    语法部分就不写了,我们直接抛出一个实际问题,看看java8的这些新特性究竟能给我们带来哪些便利 顺带用到一些泛型编程,一切都是为了简化代码 场景: 一个数据类,用于记录职工信息 public clas ...

  5. java8之lambda表达式(1)-基本语法

    lambda表达式,即带有参数的表达式,为更清晰地理解lambda表达式,先看如下例子: (1) class Student{ private String name; private Double ...

  6. java8之lambda表达式入门

    1.基本介绍 lambda表达式,即带有参数的表达式,为了更清晰地理解lambda表达式,先上代码: 1.1 两种方式的对比 1.1.1 方式1-匿名内部类 class Student{ privat ...

  7. JAVA8之lambda表达式具体解释,及stream中的lambda使用

    前言: 本人也是学习lambda不久,可能有些地方描写叙述有误,还请大家谅解及指正! lambda表达式具体解释 一.问题 1.什么是lambda表达式? 2.lambda表达式用来干什么的? 3.l ...

  8. 十分钟学会Java8的lambda表达式和Stream API

    01:前言一直在用JDK8 ,却从未用过Stream,为了对数组或集合进行一些排序.过滤或数据处理,只会写for循环或者foreach,这就是我曾经的一个写照. 刚开始写写是打基础,但写的多了,各种乏 ...

  9. java8中Lambda表达式和Stream API

    一.Lambda表达式 1.语法格式 Lambda是匿名函数,可以传递代码.使用“->”操作符,改操作符将lambda分成两部分: 左侧:指定了 Lambda 表达式需要的所有参数 右侧:指定了 ...

  10. Java8之lambda表达式

    一.什么是lambda表达式? Lambda 是一个匿名函数,我们可以把 Lambda 表达式理解为是一段可以传递的代码(将代码像数据一样进行传递).可以写出更简洁.更灵活的代码.作为一种更紧凑的代码 ...

随机推荐

  1. 以简单的例子谈一下C#中的COPY

    周五晚上加班的时候做一堆ComboBox直接的联动,然后呢,这些cbo的DataSource都是同一个DataTable,当时写代码的时候求快也就没有太注意DataTable的绑定,然后就出了一些小问 ...

  2. JS——轮播图高级版

    需求: 1.页面需要小图标和箭头 2.定时器不断的滑动图片 3.在点击箭头时,图标和图片随即做出响应 核心思想: 1.往左移动到第一张的情况:在第二张移动到第一张时,这个动画效果完成之后,立刻将ul的 ...

  3. SSH整合框架+mysql简单的实现

    SSH整合框架+mysql简单的实现 1. 框架整合原理: struts2整合Spring 两种: 一种struts2自己创建Action,自动装配Service : 一种 将Action交给Spri ...

  4. C# 获取表中最大值

    ; if (db.LPicture.Any()) { // LPicture Newmode = db.LPicture.Where(n => ).FirstOrDefault(); start ...

  5. Node.js 命令行程序开发教程 ---------http://www.ruanyifeng.com/blog/2015/05/command-line-with-node.html

    五.yargs 模块 shelljs 只解决了如何调用 shell 命令,而 yargs 模块能够解决如何处理命令行参数.它也需要安装. $ npm install --save yargs yarg ...

  6. LeetCode--不同路径

    一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” ).机器人每次只能向下或者向右移动一步.机器人试图达到网格的右下角(在下图中标记为“Finish”).现在考虑网格中 ...

  7. 笔记,js对象浅析

    学习笔记, 来源:http://www.cnblogs.com/zuiyirenjian/p/3535126.html 作者:醉意人间  此外,关于自运行函数可参考  http://benalman. ...

  8. poj3176-Cow Bowling【dp】

    The cows don't use actual bowling balls when they go bowling. They each take a number (in the range ...

  9. Dijkstra算法求最短路径

    #include <stdio.h> #include <stdlib.h> #include <string.h> #include <limits.h&g ...

  10. ISNUMERIC()检测是否为数字

    ISNUMERIC ( expression )当输入表达式得数为一个有效的整数.浮点数.money 或 decimal 类型,那么 ISNUMERIC 返回 1:否则返回 0.返回值为 1 确保可以 ...