1、lambda表达式
lambda表达式中的类型是通过上下文推断出来的,类似String[] strArr = {"as","sd"};右边元素的子类型。
匿名内部类的情况:需要引用它所在方法里的变量。这时候,需要将变量声明为final。声明为final,意味着不能为其重复赋值,同时也意味着在使用final变量时,实际上时在使用赋给该变量的一个特定的值。
java 8虽然放松了这一限制,可以引用非final变量,但是该变量在既成事实上必须是final,虽然无需将变量声明为final,但是在Lambda表达式中,也无法用作非终态变量,如果坚持用作非终态变量,编译器就会报错。
函数接口
函数接口是只有一个抽象方法的接口,用作Lambda表达式的类型
接口里面只有一个抽象方法。
接口中单一方法的命名并不重要,只要方法签名和Lambda表达式的类型匹配即可。可以在看书接口中为参数起一个有意义的名字,增加代码易读性,编译更透彻的理解参数的用途。
函数接口可以接收1个或多个参数,返回或不返回值,还可以使用泛型,这完全取决于你要干什么。
java中频繁出现的函数接口,在Java开发工具包(JDK)中提供的一组核心接口会频繁出现,大概如下,列出来你可能会便于理解下:
接口 参数 返回类型 示例
Predicate<T> T boolean 这张唱片已经发行了吗
Consume<T> T void 输出一个值
Function<T,R> T R 获取Artist对象的名字
Supplier<T> None T 工厂方法
UnaryOperator<T> T T 逻辑非(!)
BinaryOperator<T> (T,T) T 求两个数的乘机(*)
类型推断
某些情况下,用户需要手动指明类型,建议大家根据自己或者项目组的习惯,采用让代码最便于阅读的方法。有时候省略类型信息可以减少干扰,更易于弄清情况;而有时候却需要类型信息帮助理解代码。
Lambda表达式中的类型推断,实际上时java 7就引入的目标类型推断的拓展。读者可能已经知道java7中的菱形操作符,它可以使得javac推断出泛型参数的类型。
例子:使用菱形操作符省略手动声明类型
public void testGenericity(){
Map<String, Integer> oldWorldCOunts = new HashMap<String, Integer>();
Map<String, Integer> diamondWorldCounts = new HashMap<>();
useHashMap(new HashMap<>());
}
public void useHashMap(Map<String, String> values){
}
java 7中程序员可省略构造函数的泛型类型,java 8 更进一步,程序员可省略Lambda表达式中的所有参数类型。这不是魔法,javac根据Lambda表达式上下文信息就能推断出参数的正确类型。程序依然要经过类型检查来保证运行的安全性,但不再用显式声明类型罢了。这就是所谓的类型推断。
上面代码中的useHashMap(new HashMap<>())在java7中时无法通过编译的,java8中对类型推断系统进行了改善。
public void typeDeduce(){
Predicate<Integer> atLeast5 = x -> x > 5 ;
}
Predicate也是一个Lambda表达式,和前文中ActionListener不同的是,它返回一个值。在上面例子中,表达会x > 5是Lambda表达式的主体。这样的情况下,返回值就是Lambda表达式主体的值。
//Predicate接口的源码,接受一个对象,返回一个布尔值
public interface Predicate<T> {
boolean test(T t);
}
//略复杂的类型推断
BinaryOperator<Long> addLongs = (x, y) -> x + y;
类型推断系统相当智能,但若信息不够,类型推断系统也无能为力。系统不会漫无目的的瞎猜,而会终止操作并报告编译错误,寻求帮助。
BinaryOperator addLongs = (x, y) -> x + y;会报错 Operator '% #x002B;' cannot be applied to java.lang.Object, java.lang.Object.
1、lambda表达式的更多相关文章
- 你知道C#中的Lambda表达式的演化过程吗?
那得从很久很久以前说起了,记得那个时候... 懵懂的记得从前有个叫委托的东西是那么的高深难懂. 委托的使用 例一: 什么是委托? 个人理解:用来传递方法的类型.(用来传递数字的类型有int.float ...
- Linq表达式、Lambda表达式你更喜欢哪个?
什么是Linq表达式?什么是Lambda表达式? 如图: 由此可见Linq表达式和Lambda表达式并没有什么可比性. 那与Lambda表达式相关的整条语句称作什么呢?在微软并没有给出官方的命名,在& ...
- 背后的故事之 - 快乐的Lambda表达式(一)
快乐的Lambda表达式(二) 自从Lambda随.NET Framework3.5出现在.NET开发者眼前以来,它已经给我们带来了太多的欣喜.它优雅,对开发者更友好,能提高开发效率,天啊!它还有可能 ...
- Kotlin的Lambda表达式以及它们怎样简化Android开发(KAD 07)
作者:Antonio Leiva 时间:Jan 5, 2017 原文链接:https://antonioleiva.com/lambdas-kotlin/ 由于Lambda表达式允许更简单的方式建模式 ...
- java8中lambda表达式的应用,以及一些泛型相关
语法部分就不写了,我们直接抛出一个实际问题,看看java8的这些新特性究竟能给我们带来哪些便利 顺带用到一些泛型编程,一切都是为了简化代码 场景: 一个数据类,用于记录职工信息 public clas ...
- 背后的故事之 - 快乐的Lambda表达式(二)
快乐的Lambda表达式 上一篇 背后的故事之 - 快乐的Lambda表达式(一)我们由浅入深的分析了一下Lambda表达式.知道了它和委托以及普通方法的区别,并且通过测试对比他们之间的性能,然后我们 ...
- CRL快速开发框架系列教程二(基于Lambda表达式查询)
本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...
- Lambda 表达式递归用法实例
注意: 使用Lambda表达式会增加额外开销,但却有时候又蛮方便的. Windows下查找子孙窗口实例: HWND FindDescendantWindows(HWND hWndParent, LPC ...
- Spark中Lambda表达式的变量作用域
通常,我们希望能够在lambda表达式的闭合方法或类中访问其他的变量,例如: package java8test; public class T1 { public static void main( ...
- 释放Android的函数式能量(I):Kotlin语言的Lambda表达式
原文标题:Unleash functional power on Android (I): Kotlin lambdas 原文链接:http://antonioleiva.com/operator-o ...
随机推荐
- 详解maxlength属性在textarea里奇怪的表现
这篇文章主要介绍了maxlength属性在textarea里奇怪的表现的相关资料,需要的朋友可以参考下 HTML5给表单带来了很多改变,比如今天要说的maxlength,这个属性可以限制输入框输入的最 ...
- java-mybaits-00201-DAO-SqlSession使用范围
1.SqlSession的使用范围 SqlSession中封装了对数据库的操作,如:查询.插入.更新.删除等. 通过SqlSessionFactory创建SqlSession,而SqlSessionF ...
- Openstack(十七)部署快存储cinder
官方部署文档:https://docs.openstack.org/ocata/zh_CN/install-guide-rdo/cinder.html OpenStack的存储组件—Cinder和Sw ...
- jvm启动
首先使用 Java 命令启动JVM 其次进行JVM配置的装载——根据当前路径和系统的版本去寻找jvm.cfg文件,装载配置. 每种需要java虚拟机的软件,都会带一个jvm.cfg.然后jvm.cfg ...
- 创建工具条ToolBar
/***ToolBar***/ QToolBar * tlb_ImageOpen; QToolBar * tlb_VideoOpen; QToolBar * tlb_AudioOpen; void M ...
- uwsgi手动安装时报错ValueError: invalid literal for int() with base 10: '32_1'
安装uwsgi,安装步骤如下 wget https://projects.unbit.it/downloads/uwsgi-latest.tar.gz tar zxvf uwsgi-latest.ta ...
- Adobe AIR中使用Flex连接Sqlite数据库(1)(创建数据库和表,以及同步和异步执行模式)
系列文章导航 Adobe AIR中使用Flex连接Sqlite数据库(1)(创建数据库和表) Adobe AIR中使用Flex连接Sqlite数据库(2)(添加,删除,修改以及语句参数) Adobe ...
- Core Java 4
p272~p273 1.除捕获异常外的另一种异常处理方式:将异常继续传递给方法调用者. 即:在方法首部添加throws说明符号,取代 try catch语句. 对于方法的调用者而言:要么处理异常,要么 ...
- 20145211MSF基础应用实验
20145211MSF基础应用实验 一.实验博客 ms08_067攻击实验 http://www.cnblogs.com/entropy/p/6690301.html ms12_004漏洞攻击 htt ...
- 2018-2019-1 20189215 《Linux内核原理与分析》第九周作业
进程的切换和系统 <庖丁解牛>第八章书本知识总结 进程调度的时机都与中断相关,中断是程序执行过程中的强制性转移,转移到操作系统内核相应的处理程序. 软中断也叫异常,分为故障.退出和陷阱(自 ...