lambda表达式
2021-06-19 00:36:37 0 举报
AI智能生成
介绍Lambda表达式
作者其他创作
大纲/内容
什么是Lambda
Lambda概述
1. Lambda表达式也被称为箭头函数、匿名函数、闭包
2.Lambda表达式体现的是轻量级函数式编程思想
3.-> 符号是Lambda表达式核心操作符号,符号左侧是操作参数,符号右侧是操作表达式
4.JDK8新特性
MCAD模式
1. Model Code As Data,编码及数据,尽可能轻量级的将代码封装为数据
2.解决方案:接口&实现类 (匿名内部类)
3.存在问题:语法冗余、this关键字、变量捕获、数据控制等
项目问题:功能接口设计及优化
1.需求环境:线程类的创建
2.解决方案:匿名内部类实现
3.优化方案:lambda表达式实现
为什么要用Lambda
1.它不是解决未知问题的新技术
2.对现有解决方案的语义化优化
3.需要根据实际需求考虑性能问题
Lambda基础
函数式接口(function interface)
函数式接口,就是Java类型系统中的接口
函数式接口,是只包含一个接口方法的特殊接口
语义化检测注解:@FunctionalInterface
默认接口方法
给所有子类增加默认的实现
静态接口方法
java.util.function提供了大量的函数式接口
1. Predicate 接收参数T对象,返回一个boolean类型结果
2. Consumer 接收参数T对象,没有返回值
3. Function 接收参数T对象,返回R对象
4. Supplier 不接收任何参数,直接通过get()获取指定类型的对象
5. UnaryOperator 接收参数T对象,执行业务处理后,返回更新后的T对象
6. BinaryOperator 接收两个T对象,执行业务处理后,返回一个T对象
Lambda基本语法
1.声明:就是和lambda表达式绑定的接口类型
2.参数:包含在一对圆括号中,和绑定的接口中的抽象方法中的参数个数及顺序一致
3.操作符: ->
4.执行代码块:包含在一对大括号中,出现在操作符号的右侧
[接口声明] = (参数) -> {执行代码块};
变量捕获
匿名内部类中的变量捕获
Lambda表达式中的变量捕获
类型检查
表达式类型检查
参数类型检查
方法重载的问题
1.java类型系统中的方法重载
2.方法重载的实现
3.当方法重载遇上Lambda表达式
Lambda运行原理
Lambda高级
方法引用
方法引用是结合Lambda表达式的一种语法特性
静态方法引用
实例方法引用
构造方法引用
Stream API
1.Stream聚合操作
2. stream的处理流程
数据源
数据转换
获取结果
3.获取stream对象
1.从集合或数组中获取(重要)
Collection.stream() 串行迭代
Collection.parallelStream() 并行迭代
Arrays.stream(T t)
2.BufferReader
BufferReader.lines() -> stream()
3.静态工厂
java.util.stream.IntStream.range()..
java.nio.file.Files.walk()..
4.自行构建
java.util.Spliterator
5.更多的方式
Random.ints()
Pattern.splitAsStream()
4. 中间操作API {intermediate}
概述
操作结果是一个Stream,中间操作可以有一个或多个连续的中间操作,需要注意的是,
中间操作只记录操作方式,不做具体执行,直到结束操作发生时,才做数据的最终执行。
中间操作:就是业务逻辑处理。
中间操作只记录操作方式,不做具体执行,直到结束操作发生时,才做数据的最终执行。
中间操作:就是业务逻辑处理。
划分
无状态
数据处理时,不受前置中间操作的影响。
map/filter/peek/parallel/sequential/unordered
有状态
数据处理时,受到前置中间操作的影响。
distinct/sorted/limit/skip
5. 终结/结束操作 {terminal}
概述
一个Stream对象,只能有一个Terminal操作,这个操作一旦发生,就会真实处理数据,生成对应的处理结果。
划分
非短路操作
当前的Stream对象必须处理完集合中所有数据,才能得到处理结果。
forEach/forEachOrdered/toArray/reduce/collect/min/max/count/iterator
短路操作
Short-circuiting
Short-circuiting
当前的Stream对象在处理过程中,一旦满足某个条件,就可以得到结果。
anyMatch/allMatch/noneMatch/findFirst/findAny等
使用场景:无限大的Stream -> 有限大的Stream
Stream原理
集合元素操作
类型转换:其他类型(创建/获取) -> Stream对象
类型转换:Stream对象 -> 其他类型
Stream常见API操作
Lambda和Stream的性能
参赛选手
1.stream 串行迭代
2.parallelStream 并行迭代
3. 普通for循环
4. 增强for循环
5. Iterator 迭代器循环
结论
1.迭代基本数据类型的集合时,stream性能最低;建议采用 3/4/5,其中 5性能最高
2. 迭代复杂数据类型的集合时,也就是对象列表这种,
stream性能已经接近普通迭代,甚至超过普通迭代,完全可以通过简洁的stream语法来替换普通迭代;
另外,如果项目对性能有较高要求的话,则可以采用parallelStream来迭代。
stream性能已经接近普通迭代,甚至超过普通迭代,完全可以通过简洁的stream语法来替换普通迭代;
另外,如果项目对性能有较高要求的话,则可以采用parallelStream来迭代。
并行stream存在线程安全问题
迭代的时候,竟然存在数据丢失的情况!!!
解决方案
1.用stream API中线程安全的终端操作来执行
比如:lists.parallelStream().forEach(x->list2.add(x));是线程不安全的;
但是用 lists.parallelStream().collect(Collectors.toList());就是线程安全的
但是用 lists.parallelStream().collect(Collectors.toList());就是线程安全的
2.加线程锁
3.直接使用线程安全的集合来规范数据源(较多的场景)
0 条评论
下一页