java8语法特性-Lambda表达式、Stream API学习¶
Lambda表达式:Lambda允许把函数作为一个方法的参数(函数作为参数传递到方法中)。
Stream API:新添加的Stream API(java.util.stream)把真正的函数式编程风格引入到Java中。
Lambda表达式¶
Lambda表达式可以用于替换单方法接口
在Java编程语言中,Lambda表达式是一种函数式编程的特性,它提供了一种简洁的方式来创建匿名函数。Lambda表达式可以被视为一种更简洁的匿名类的写法。
Lambda表达式的语法由箭头符号(->)分隔成两部分。箭头左侧是参数列表,箭头右侧是表达式主体。Lambda表达式是一个可以被分配给函数式接口(Functional Interface)的对象,该接口必须只包含一个抽象方法。
我们把只定义了单方法的接口称之为FunctionalInterface,用注解@FunctionalInterface标记。
Lambda表达式的形式如下: (param1, param2, ...) -> { 表达式主体 }
下面是一个简单的Lambda表达式的示例:
int[] numbers = {1, 2, 3, 4, 5};
在上述示例中,Lambda表达式 (n -> n * 2) 是一个函数式接口的实现。它接受一个参数n,并返回n乘以2的结果。这个Lambda表达式被应用于Stream的map操作,用于对数组中的每个元素进行处理。
使用Lambda表达式可以简化代码,使代码更加易读和简洁。Lambda表达式通常可以取代使用匿名内部类的方式来实现函数式接口,减少了冗余的代码和额外的类定义。
需要注意的是,Lambda表达式只能用于函数式接口。函数式接口是只有一个抽象方法的接口,可以使用@FunctionalInterface注解进行标识。对于抽象方法多于一个的接口,无法使用Lambda表达式。
Stream API¶
Java 8 Stream | 菜鸟教程 (runoob.com)
https://www.liaoxuefeng.com/wiki/1252599548343744/1322402873081889
https://blog.csdn.net/const_/article/details/96302525
https://cloud.tencent.com/developer/article/1746942
这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。
元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。
Stream API的特点是:
- Stream API提供了一套新的流式处理的抽象序列;
- Stream API支持函数式编程和链式操作;
- Stream可以表示无限序列,并且大多数情况下是惰性求值的。
Stream API的基本用法就是:创建一个Stream,然后做若干次转换,最后调用一个求值方法获取真正计算的结果:
Stream.map()¶
Stream.map()是Stream最常用的一个转换方法,它把一个Stream转换为另一个Stream。
在其中可以使用lambda表达式.map(s -> s.replaceAll(" ", ""))
还可以使用方法调用.map(LocalDate::parse)
英文格式双冒号::,读:double colon,双冒号(::)运算符在Java 8中被用作方法引用(method reference),方法引用是与lambda表达式相关的一个重要特性。它提供了一种执行方法的方法,为此,方法引用需要由兼容的函数式接口组成的目标类型上下文。
大致意思是,使用lambda表达式会创建匿名方法, 但有时候需要使用一个lambda表达式只调用一个已经存在的方法(不做其它), 所以这才有了方法引用!
常用语法
- 静态方法引用语法:className::methodName 例如:Person::getAge
- 对象的实例方法引用语法:instanceName::methodName 例如:System.out::println
- 对象的超类方法引用语法:super::methodName
- 类构造器引用语法:className::new 例如:ArrayList::new
- 数组构造器引用语法:typename[]::new 例如:String[]::new
Stream.filter()¶
Stream.filter()是Stream的另一个常用转换方法。
所谓filter()操作,就是对一个Stream的所有元素一一进行测试,不满足条件的就被“滤掉”了,剩下的满足条件的元素就构成了一个新的Stream。
Stream.reduce()¶
map()和filter()都是Stream的转换方法,而Stream.reduce()则是Stream的一个聚合方法,它可以把一个Stream的所有元素按照聚合函数聚合成一个结果。reduce()是聚合方法,聚合方法会立刻对Stream进行计算。
stream.reduce((acc, n) -> acc + n)
接收两个参数,第一个是sum聚合的初始值,第二个是聚合方法,常为一个lambda表达式
流的特点是每个元素只遍历一次,聚合操作无非就是一个遍历+累加计算的过程,内部已经自动帮你遍历了
你想再遍历一遍,那只能构造一个新的stream
输出集合¶
我们介绍了Stream的几个常见操作:map()、filter()、reduce()。这些操作对Stream来说可以分为两类,一类是转换操作,即把一个Stream转换为另一个Stream,例如map()和filter(),另一类是聚合操作,即对Stream的每个元素进行计算,得到一个确定的结果,例如reduce()。
区分这两种操作是非常重要的,因为对于Stream来说,对其进行转换操作并不会触发任何计算!
输出为list:调用collect()并传入Collectors.toList()对象
输出为set:collect(Collectors.toSet())可以把Stream的每个元素收集到Set中
分组输出:分组输出使用Collectors.groupingBy(),它需要提供两个函数:一个是分组的key,这里使用s -> s.substring(0, 1),表示只要首字母相同的String分到一组,第二个是分组的value,这里直接使用Collectors.toList(),表示输出为List
分组输出练习
输出
排序¶
注意sorted()只是一个转换操作,它会返回一个新的Stream。
去重¶
对一个Stream的元素进行去重,没必要先转换为Set,可以直接用distinct()
Stream提供的常用操作有:
转换操作:map(),filter(),sorted(),distinct();
合并操作:concat(),flatMap();
并行处理:parallel();
聚合操作:reduce(),collect(),count(),max(),min(),sum(),average();
其他操作:allMatch(), anyMatch(), forEach()。
Java双冒号(::)运算符¶
在 Java 中,"::" 是一个方法引用运算符,也称为方法引用符。它的作用是将方法转换为对象。
MyBatis-Plus条件构造器LambdaQueryWrapper¶
- CRUD接口
- service CRUD接口
- 继承
iService,在controller中调用
- 继承
- mapper CRUD接口
- 继承
BaseMapper,在serviceImpl中调用
- 继承
- service CRUD接口
- 条件构造器
用于向crud接口中传递查找条件