java8(一)Lambda表达式
其实很久前已经学习过了Lambda表达式,但是学习后没有多少使用的机会,久而久之也就忘记(惭愧)。最近新的项目用的jdk8所以准备再学习一次,写下文章也是为了记录,方便以后再忘的时候,不用到处找资料(旁白:这么丢人的事,能别到处说吗)。
语法
(参数) -> 表达式或(参数) -> {表达式}
第一个Lambda表达式
public class Java8Lambda { @Test public void test1() { // lambda表达式 Greeting helloLambda = (name) -> "Hello! " + name; // 调用方法 System.out.println(helloLambda.sayHello("Lambda")); } interface Greeting { String sayHello(String name); }}
输出结果:
Hello! Lambda
Lambda表达式可以看成是匿名类一点点演变过来
匿名类的写法
@Testpublic void test2() { // 匿名类的写法 Greeting helloLambda = new Greeting() { @Override public String sayHello(String name) { return "Hello! " + name; } }; // 调用方法 System.out.println(helloLambda.sayHello("Lambda"));}
设计匿名内部类的目的,就是为了方便java程序员将代码作为数据传递。不过匿名内部类还是不够简便。
去除外壳,保留方法参数和方法体,并在参数和方法体之间加上符号->(这里已经变成Lambda了,但不是最简洁的,请往下看)
@Testpublic void test3() { // 去除外壳,保留方法参数和方法体,并在参数和方法体之间加上符号-> Greeting helloLambda =(String name) -> { return "Hello! " + name; }; // 调用方法 System.out.println(helloLambda.sayHello("Lambda"));}
去除return和{}
@Testpublic void test4() { // 去除return和{} Greeting helloLambda =(String name) -> "Hello! " + name; // 调用方法 System.out.println(helloLambda.sayHello("Lambda"));}
去除参数类型和圆括号(只有一个参数的时候,才可以去掉圆括号)
@Testpublic void test5() { // 去除参数类型和圆括号(只有一个参数的时候,才可以去掉圆括号) Greeting helloLambda = name -> "Hello! " + name; // 调用方法 System.out.println(helloLambda.sayHello("Lambda"));}
从test2到test5代码一步步变的简介紧凑,与匿名类相比Lambda更加简洁。
函数式接口
函数式接口是只有一个抽象方法的接口,使用Lambda表达式的接口都是函数式接口。
Lambda表达式允许你直接以内联的形式为函数式接口的抽象方法提供实现,并把整个表达式作为函数式接口的实例。
函数式接口还带有一个注解@FunctionalInterface,这个注解帮助开发者判断接口是否是函数式接口,如果接口不是函数式接口,编译器将会返回一个提示错误。例如:Multiple non-overriding abstract methods found in interface com.straymalone.java8demo.Java8Lambda.Greeting,表明存在多个抽象方法。注意,@FunctionalInterface不是必须的,但是对于为此设计的接口而言,使用它是比较好的做法。它就像@Override注解表示方法被重写了。
类型推断
某些情况下,用户需要手动指明Lambda参数的类型,例如:
@Testpublic void test6() { BinaryOperator<Long> addLongs = (x, y) -> x + y; // 去掉<Long>会报错哦 // 调用方法 System.out.println(addLongs.apply(2L, 3L));}
这时将泛型<Long>去掉编译器将会报错,提示如下:
Operator '+' cannot be applied to 'java.lang.Object', 'java.lang.Object'
BinaryOperator 毕竟是一个具有泛型参数的函数接口, 该类型既是参数 x 和 y 的类型, 也是返回值的类型。 上面的例子中并没有给出变量add 的任何泛型信息, 给出的正是原始类型的定义。 因此, 编译器认为参数和返回值都是java.lang.Object 实例。
所以这个时候如果没有泛型就会编译报错。
Lambda表达式的重要特征
可选的类型声明:有时省略类型信息可以减少干扰,更易弄清状况;而有时却需要类型信息帮助理解代码
可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号
可选的大括号:如果主题包含了一个语句,就不需要使用大括号
可选的返回关键字:如果主题只有一个表达式返回值则编译器会自动返回值,如果使用大括号说明不止一个语句,必须声明返回值。
可选的注解@FunctionalInterface:检测接口是否是函数式接口
参考资料
《Java 8函数式编程》
《Java 8实战》
java8(一)Lambda表达式的更多相关文章
- Java8中Lambda表达式的10个例子
Java8中Lambda表达式的10个例子 例1 用Lambda表达式实现Runnable接口 //Before Java 8: new Thread(new Runnable() { @Overri ...
- java8的lambda表达式,将List<DTO> 转为 List<DO>
将List<PhoneDTO>转为List<PhoneDO>,通过java8的lambda表达式来操作,比传统的for循环精简很多: /** * List<PhoneDT ...
- java8的lambda表达式
关于java8的lambda表达式 lambda表达式一般用于接口,因为lambda表达式是函数式编程. 1.有且仅有一个抽象方法被称为函数式接口,函数式接口可以显示的被@FunctionalInte ...
- java8中lambda表达式的应用,以及一些泛型相关
语法部分就不写了,我们直接抛出一个实际问题,看看java8的这些新特性究竟能给我们带来哪些便利 顺带用到一些泛型编程,一切都是为了简化代码 场景: 一个数据类,用于记录职工信息 public clas ...
- java8之lambda表达式(1)-基本语法
lambda表达式,即带有参数的表达式,为更清晰地理解lambda表达式,先看如下例子: (1) class Student{ private String name; private Double ...
- java8之lambda表达式入门
1.基本介绍 lambda表达式,即带有参数的表达式,为了更清晰地理解lambda表达式,先上代码: 1.1 两种方式的对比 1.1.1 方式1-匿名内部类 class Student{ privat ...
- JAVA8之lambda表达式具体解释,及stream中的lambda使用
前言: 本人也是学习lambda不久,可能有些地方描写叙述有误,还请大家谅解及指正! lambda表达式具体解释 一.问题 1.什么是lambda表达式? 2.lambda表达式用来干什么的? 3.l ...
- 十分钟学会Java8的lambda表达式和Stream API
01:前言一直在用JDK8 ,却从未用过Stream,为了对数组或集合进行一些排序.过滤或数据处理,只会写for循环或者foreach,这就是我曾经的一个写照. 刚开始写写是打基础,但写的多了,各种乏 ...
- java8中Lambda表达式和Stream API
一.Lambda表达式 1.语法格式 Lambda是匿名函数,可以传递代码.使用“->”操作符,改操作符将lambda分成两部分: 左侧:指定了 Lambda 表达式需要的所有参数 右侧:指定了 ...
- Java8之lambda表达式
一.什么是lambda表达式? Lambda 是一个匿名函数,我们可以把 Lambda 表达式理解为是一段可以传递的代码(将代码像数据一样进行传递).可以写出更简洁.更灵活的代码.作为一种更紧凑的代码 ...
随机推荐
- 仿照Spring自己实现有各种通知的AOP,AOP实现的步骤分解
一.需求: 仿照Spring的AOP写的 MyAOP 2.0,有环绕通知.前置通知.后置通知.返回通知.异常通知等. 已实现:①通过动态代理+通知的注解类,实现了前置通知.后置通知等各种通知:②切点( ...
- 如何提高Sprint Review的质量?
Sprint Review不是回顾,其目标是演示这个Sprint中自己的工作成果,参会人员包括设计师.开发人员和Product Owner.在Worktile,我们尽量保持Sprint评审会的轻松随意 ...
- 分布式事务(2)---TCC理论
分布式事务(2)---TCC理论 上篇讲过有关2PC和3PC理论知识,博客:分布式事务(1)---2PC和3PC理论 我的理解:2PC.3PC还有TCC都蛮相似的.3PC大致是把2PC的第一阶段拆分成 ...
- Java内部类你真的会吗?
一.四种内部类 1.1.成员内部类 成员内部类是最普通的内部类,它的定义为位于另一个类的内部,形如下面的形式: public class OuterAndInnerClass { public sta ...
- 用Python玩数据-笔记整理-第一章-练习与测试
编程题: 简单的输入输出:编程实现输入姓.名的提示语并接受用户输入,并单独显示姓.名和全名,执行效果如下所示: Input your surname:ZHANG Input your firstnam ...
- samba搭建与配置说明
1. 环境检查getenforce 检查selinux service iptables stop 2.安装samba yum -y install samba 3.配置samba /etc/samb ...
- 使用MyBatis在控制台动态打印执行的sql语句
使用MyBatis进行数据库操作的时候,sql语句都是写在相应的mapper文件中,参数也是使用占位符取值表示的,mapper文件中看不到实时执行的完整sql,有时候sql语句错误或者参数类型不对的时 ...
- 【题解】【A % B Problem(P1865)】-C++
题目背景 题目名称是吸引你点进来的 实际上该题还是很水的 题目描述 区间质数个数 输入输出格式 输入格式: 一行两个整数 询问次数n,范围m 接下来n行,每行两个整数 l,r 表示区间 输出格式: 对 ...
- Oracle粗心大意总结篇
有时候写sql语句不细心的话,很容易犯大错误,导致你纠结好久,找不到原因,慢慢总结: 错误1: SELECT * FROM( SELECT USER.*, ROWNUM AS CON FROM USE ...
- 关于RedirectAttributes 重定向带参数请求问题
@RequestMapping("/delete") public String delete(String id, RedirectAttributes redirectAttr ...