lambda表达式学习使用实例
目录
- 前言
- `lambda` 语法
- 基本语法:
- 基本语法的具体示例:
- `lambda` 语法使用
- 用 `lambda` 表达式实现 `Runnable`
- `lambda` 表达式实现 `forEach` 遍历集合
- 实体类
- 使用语法: `x -> 2 * x` 进行 `forEach` 遍历
- `forEach` 遍历的语法解析
- 使用双冒号 `::` 进行 `forEach` 遍历
- 双冒号`::`(方法引用)的语法解析
前言
在对 Java8
发布的 Lambda
表达式进行一定了解之后,发现 Lambda
最核心的就是结合 Stream API
对集合数据的遍历、提取、过滤、排序等一系列操作的简化,以一种函数式编程的方式,对集合进行操作
lambda
表达式就是函数接口类型的实例
lambda
语法
基本语法:
(parameters) -> expression 或 (parameters) ->{ statements; }
基本语法的具体示例:
// 1. 不需要参数,返回值为 5
() -> 5 // 2. 接收一个参数(数字类型),返回其2倍的值
x -> 2 * x // 3. 接受2个参数(数字),并返回他们的差值
(x, y) -> x – y // 4. 接收2个int型整数,返回他们的和
(int x, int y) -> x + y // 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)
(String s) -> System.out.print(s)
lambda
语法使用
用 lambda
表达式实现 Runnable
lambda
表达式替换了原来匿名内部类
的写法,没有了匿名内部类繁杂的代码实现,而是突出了,真正的处理代码。最好的示例就是实现 Runnable
的线程实现方式了: 用 () -> {}
代码块替代了整个匿名类
public class LambdaTest1 {public static void main(String[] args) {// 使用匿名内部类 实现多线程new Thread(new Runnable() {@Overridepublic void run() {System.out.println("匿名内部类 实现多线程");}}).start();// 使用的lambda表达式语法为:() -> 5new Thread(() -> System.out.println("使用lambda表达式")).start();}
}
结果
匿名内部类 实现多线程
使用lambda表达式
lambda
表达式实现 forEach
遍历集合
实体类
public class Person {private String name;private int age;private String sex;public Person(String name, int age, String sex) {this.name = name;this.age = age;this.sex = sex;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +", sex='" + sex + '\'' +'}';}// set,get 方法省略
}
使用语法: x -> 2 * x
进行 forEach
遍历
public class LambdaTest3 {@NotNullpublic static List<Person> getPersonList() {Person p1 = new Person("liu", 22, "male");Person p2 = new Person("zhao", 21, "male");Person p3 = new Person("li", 18, "female");Person p4 = new Person("wang", 21, "female");List<Person> list = new ArrayList<>();list.add(p1);list.add(p2);list.add(p3);list.add(p4);return list;}public static void main(String[] args) {List<Person> personList = LambdaTest3.getPersonList();// 使用 lambda 表达式 forEach 遍历personList.forEach(person -> System.out.println(person.toString()));}
}结果:
Person{name='liu', age=22, sex='male'}
Person{name='zhao', age=21, sex='male'}
Person{name='li', age=18, sex='female'}
Person{name='wang', age=21, sex='female'}
forEach
遍历的语法解析
personList.forEach(person -> System.out.println(person.toString()));
查看 forEach
的源码,我们发现接收的参数类型为:Consumer<? super T> action
default void forEach(Consumer<? super T> action) {Objects.requireNonNull(action);for (T t : this) {action.accept(t);}
}
因此可推断 lambda
表达式的类型:
Consumer<Person> action = person -> System.out.println(person.toString());
如何理解这句代码呢?先看 java.util.function.Consumer
的源码:
@FunctionalInterface
public interface Consumer<T> {void accept(T t);...(省略default方法)
}
我们发现它是一个函数接口,通俗的话讲:函数接口是指只含有一个抽象方法的接口,在 Java8
中,接口里面可以存在已实现的方法,如:default
默认方法、static
静态方法
注意:@FunctionalInterface
注解的作用,当函数接口中存在两个或两个以上的抽象方法时,编译会报错
所以,我们可以这样理解:person -> System.out.println(person.toString())
就是实现了 Consumer
接口中 accept
方法的实例,->
前面的部分 e
表示 accept
方法的入参,->
后面的部分表示 accept
方法的具体实现
注意:
- 如果方法的实现部分由多行代码组成,就用
{}
括起来 - 如果方法需要返回值,而且方法体只有一行代码,可以省略
return
。如果方法体有多行代码,则不能省略return
使用双冒号 ::
进行 forEach
遍历
public class LambdaTest3 {@NotNullpublic static List<Person> getPersonList() {Person p1 = new Person("liu", 22, "male");Person p2 = new Person("zhao", 21, "male");Person p3 = new Person("li", 18, "female");Person p4 = new Person("wang", 21, "female");List<Person> list = new ArrayList<>();list.add(p1);list.add(p2);list.add(p3);list.add(p4);return list;}public static void main(String[] args) {List<Person> personList = LambdaTest3.getPersonList();// 使用 lambda 表达式 forEach 遍历Consumer<Person> consumer = e -> e.setAge(e.getAge() + 3);personList.forEach(consumer);personList.forEach(System.out::println);}
}结果:
Person{name='liu', age=25, sex='male'}
Person{name='zhao', age=24, sex='male'}
Person{name='li', age=21, sex='female'}
Person{name='wang', age=24, sex='female'}
双冒号::
(方法引用)的语法解析
personList.forEach(System.out::println);
之前说过,lambda
表达式就是函数接口类型的实例,而创建该实例的过程,需要实现函数接口中的抽象方法。因此,可以采用引用的方式,即引用已定义好的方法去实现函数接口中的方法
那么 System.out::println
该如何理解?同样根据上下文推断 lambda
表达式的类型:
Consumer action = System.out::println;
System.out::println
的函数接口类型为 java.util.function.Consumer
,即在产生该实例对象时,引用了 System.out
对象中的 println
方法,去实现了 Consumer
接口中的 accept
抽象方法。简而言之,即:引用 println
方法去实现了接口中的抽象方法
方法引用有很多种,下面主要讲述以下几种:
- 构造方法引用:
Class::new
- 静态方法引用:
ClassName::methodName
- 实例上的实例方法引用:
instanceReference::methodName
- 类型上的实例方法引用:
ClassName::methodName
方法引用详情查看
文章未完成,后续更新
lambda表达式学习使用实例相关推荐
- java lambda表达式学习笔记
lambda是函数式编程(FP,functional program),在java8中引入,而C#很早之前就有了.在java中lambda表达式是'->',在C#中是'=>'. 杜甫说:射 ...
- [研究笔记]Lambda表达式学习笔记
最近正好用到,就稍微做一下学习笔记.全部经过自己理解的归纳总结,坚持更新. Lambda表达式强大到和图灵机等价,而且极其简洁.优美,太好玩了! ==== Formal Defination Lamb ...
- Python中lambda表达式学习
lambda只是一个表达式,函数体比def简单很多. lambda的主体是一个表达式,而不是一个代码块.仅仅能在lambda表达式中封装有限的逻辑进去. lambda表达式是起到一个函数速写的作用.允 ...
- java中的lambda表达式学习
Lambda表达式是给函数式接口(SAM接口)的变量或形参赋值的表达式. Lambda表达式替代了原来使用匿名内部类的对象给函数式接口(SAM接口)的变量或形参赋值的形式. java提供了大量的函数式 ...
- lambda表达式学习(详细理解 ) 重点在最后
多线程的runable接口,如果你的代码简单就可以用lambda简化 package cn.com.zzn.lambda;public class TestLambda2 {// 静态内部类/* st ...
- mybatis-plus lambda表达式学习笔记
使用mybatis-plus的好处在于可以通过Java代码实现Sql逻辑,不需要像mybatis需要通过xml编写Sql语句操作数据库,实现了零配置和手写Sql的烦恼. mybatis-plus中的l ...
- Lambda表达式学习
项目里面需要经常对一系列同类型集合进行操作,如对集合进行增加元素,删除集合的指定索引的元素等等. 我们可以使用ArrayList来进行.如 ArrayList stringArrayList=new ...
- lambda表达式学习例子
https://www.cnblogs.com/franson-2016/p/5593080.html 实例 表达式 说明 将仓库数据,以id为key,仓库数据为value Map<Long ...
- 学习Kotlin(五)函数与Lambda表达式
推荐阅读: 学习Kotlin(一)为什么使用Kotlin 学习Kotlin(二)基本语法 学习Kotlin(三)类和接口 学习Kotlin(四)对象与泛型 学习Kotlin(五)函数与Lambda表达 ...
- java里函数式表达式_Java8函数式编程 (一) 数据流和lambda表达式
JDK 1.8中引入了函数式编程(functional programming,FP),如果您已习惯OOP,一定会感到困惑:什么是函数式编程?这样的编程模式有什么好处? 本文将通过简单的实例令读者对函 ...
最新文章
- 未来网络经济的99个趋势报告
- 集成IDE anaconda
- v-on绑定特性命名带小横杠 ‘-’与props属性中变量怎么对应
- java队列实现限流,java中应对高并发的两种策略
- [Contest20180418]物理竞赛
- 打开应用中SQLite文件的方法
- 查询mysql当前连接并删除_查看mysql已有用户并删除
- 课程设计—通讯录管理系统
- 模式识别算法中英文对照
- 江苏海洋大学c语言期末考试题库,海南热带海洋学院18级C语言期末考试PAT编程题...
- linux下mysql定时备份
- Android WebView调用摄像头录像拍照处理
- android水下气泡,科学网—水下爆炸气泡的基本现象及规律 - 黄超的博文
- Java HotSpot(TM) 64-Bit Server VM warning:
- 深度学习-感受野与有效感受野
- 【架构思维】:设计服务降级的思路与方法
- 妇产科护理学名词解释
- 今天我的app上线了庆祝一下
- SpringMVC学习----请求与响应
- html th中加斜杠,vue element 表头添加斜线
热门文章
- Java中的【锁】事 - 极客大学架构师训练营 架构师 Albert 分享
- 用大数据挑选出国外最值得看的前50条swift教程(v.2019)
- 字符流中第一个只出现一次的字符
- 机器学习中性能评估指标中的准确率(Accuracy)、召回率(Recall=TPR)、精确率(Precision)、误报率(FPR)、漏报率(FNR)及其关系
- vscode php断点调试,如何使用vscode断点调试laravel
- hadoop配置集群的心得
- 2018_08_10_生活记录_关于我和这个博客的说明
- 强化学习各概念整理(value/policy-based、on/off-policy、model-based/free、offline)
- MATLAB 均值估计函数normfit
- LaTeX 报错 Underfull \hbox (badness 10000)