文档章节

Java Lambda表达式(一)

兴趣使然的程序员
 兴趣使然的程序员
发布于 2017/02/24 17:11
字数 867
阅读 55
收藏 3

Lambda表达式简介

Java 8新引入Lambda表达式。

注意Lambda表达式只能用来替代函数式接口(函数式接口是只包含有一个抽象方法的接口,哪怕有很多个默认方法,只有只有一个抽象方法,就是函数式接口)!甚至不能把Lamda表达式赋值给Object!即仍然保持使用接口的习惯,只是将接口的实现类编写简化成Lambda表达式。具体来说,Lambda表达式其实是函数式接口中的函数的实现

推荐给所有的函数式接口上加上@FunctionalInterface,表示这是一个函数式接口。

举例说明:

Comparator是一个接口,主要用于Arrays类的静态排序方法sort里指定排序的规则。

比如如果希望对字符串进行排序,排序规则为字符串的长度。如果不用Lambda表达式的话,我们一般会用一个匿名内部类来实现:

//创建Compartor接口的匿名实现
Comparator<String> comparator = new Comparator<String>() {
      @Override
      public int compare(String o1, String o2) {
           return Integer.compare(o1.length(),o2.length());
      }
};

//调用comparator对象进行排序
String[] words = new String[]{"l1111","l222"};
Arrays.sort(words,comp);

Lambda表达式的作用即在于替代上面的匿名实现部分,即:

//使用Lambda表达式写函数式接口实现
Comparator<String> comp = (first,second)->Integer.compare(first.length(),second.length());

固使用Lambda表达式有两个条件:

  1. 定义好的函数式接口
  2. 定义好的调用该函数式接口的方法

当然,由于Lambda表达式一般是“一次性用品”,所以一般我们会这样写:

Arrays.sort(words,(first,second)->Integer.compare(first.length(),second.length()));

由于隐去了接口对象的声明,同时隐去了变量类型的声明,所以有一些代码显得不明所以。

最后提示:

  1. 不需要声明参数的类型
  2. 不需要声明返回值的类型,在简单的情况下甚至不需要使用return。在比较复杂的情况下,可以像写方法一样写Lambda表达式,使用(x1,x2)->{    /*注意这里是花括号 */     };的形式写lambda表达式
  3. Lambda表达式可以没有限制地使用参数、实例变量和静态变量,但是如果想使用局部变量则必须显式地使用final修饰

Lambda表达式和闭包

闭包就是一个函数的实例,且它可以无限制地访问那个函数的非本地变量。例如,闭包可以作为参数传递给另一个函数。它也可以访问和修改其作用域之外的变量。

现在, Java 8的Lambda和匿名类可以做类似于闭包的事情:它们可以作为参数传递给方法,并且可以访问其作用域之外的变量。但有一个限制:它们不能修改定义Lambda的方法的局部变量的内容。这些变量必须是隐式最终的。可以认为Lambda是对值封闭,而不是对变量封闭。

这种限制存在的原因在于局部变量保存在栈上,并且隐式表示它们仅限于其所在线程。如果允许捕获可改变的局部变量,就会引发造成线程不安全的新的可能性,而这是我们不想看到的(实例变量可以,因为它们保存在堆中,而堆是在线程之间共享的) 。
 

© 著作权归作者所有

共有 人打赏支持
兴趣使然的程序员
粉丝 21
博文 112
码字总数 87412
作品 0
深圳
程序员
私信 提问
Java 8 lambda 表达式 示例

Java8中的Lambda表达式取代了匿名类,取消了模板,允许用函数式风格编写代码。这样有时可读性更好,表达更清晰。作为开发人员,我发现学习和掌握lambda表达式的最佳方法就是勇于尝试,尽可能...

阿刚ABC
10/14
0
0
02、Java的lambda表达式和JavaScript的箭头函数

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

weir_will
06/14
0
0
Java8 - lambda 表达式

lambda表达式 为什么需要lambda 表达式 函数对 Java 而言并不重要,在 Java 的世界里,函数无法独立存在。Lambda 表达式为 Java 添加了缺失的函数式编程特点,使我们能将函数当做一等公民看待...

秋风醉了
08/29
0
0
Lambda 表达式有何用处?如何使用?(针对Java8)

什么是Lambda? 我们知道,对于一个Java变量,我们可以赋给其一个“值”。 如果你想把“一块代码”赋给一个Java变量,应该怎么做呢? 比如,我想把右边那块代码,赋给一个叫做aBlockOfCode的J...

亭子happy
06/06
0
0
java8函数表达式的定义[Definition of a Lambda Expression]

英文来源于:Java in a Nutshell, 6th Edition            Definition of a Lambda Expression A lambda expression is essentially a function that does not have a name, and ......

Beaver_
2015/03/13
0
0

没有更多内容

加载失败,请刷新页面

加载更多

剖析Elasticsearch的IndexSorting:一种查询性能优化利器

摘要: 前言 前两周写过一篇《基于Lucene查询原理分析Elasticsearch的性能》,在最后留了一个彩蛋,说下一篇会介绍一种可以极大的优化查询性能的技术。本文就来介绍这种技术——IndexSortin...

阿里云官方博客
31分钟前
1
0
Go 使用channel控制并发

前言 channel一般用于协程之间的通信,channel也可以用于并发控制。比如主协程启动N个子协程,主协程等待所有子协程退出后再继续后续流程,这种场景下channel也可轻易实现。 场景示例 总结 ...

恋恋美食
56分钟前
3
0
斐波那契堆的理解,节点mark属性和势函数

斐波那契堆 看了好多博客,都是照搬算法导论的内容,没有自己的理解,比如为什么有mark属性,势函数的作用,以及为什么叫斐波那契堆,下面说说鄙人的理解。 势函数 势函数是根节点个数加上2...

杨喆
今天
7
0
NIO源码详解

阻塞io和无阻塞io: 阻塞io是指jdk1.4之前版本面向流的io,服务端需要对每个请求建立一堆线程等待请求,而客户端发送请求后,先咨询服务端是否有线程相应,如果没有则会一直等待或者遭到拒 ...

沉稳2018
今天
2
0
如何把已经提交的commit, 从一个分支放到另一个分支

在本地master提交了一个commit(8d85d4bca680a5dbcc3e5cfb3096d18cd510cc9f),如何提交的test_2分之上? git checkout test_2git cherry-pick 8d85d4bca680a5dbcc3e5cfb3096d18cd510cc9f......

stephen_wu
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部