1.分类:
Lambda表达式:核心
函数式接口:
方法引用与构造器引用:
Stream API:核心
接口中默认方法与静态方法:
新时间日期 API:
其他新特性:
2.优点:
速度更快:
代码更少:增加了新的语法 Lambda 表达式
强大的 StreamAPI:
便于并行:
最大化减少空指针异常 Optional:
3.为什么使用Lambda表达式:
4.lambda表达式基本格式:
(参数列表) -> {代码}
重点:函数式编程只关注参数和方法体,方法名之类都不关注
5.技巧:使用时用 alt+enter 快捷键,就能将传统代码转成lambda格式或将lambda格式转成传统代码格式
6.省略规则
1》参数类型可以省略
2》方法体只有一句代码时大括号return和唯一一句代码的分号可以省略
3》方法只有一个参数时,小括号可以省略
4》以上规则都可以省略不记,使用idea的快捷键 alt+enter
7.stream流:
定义:她是对集合或者数组进行链状流式的操作
8.创建stream流的3种方式:
1》单例集合:集合对象.stream()
2》数组:Arrays.stream(数组) 或 Stream.of(数组) 来创建
3》双例集合:转换成单例集合后再创建
9.中间操作:
1》filter:对流中的元素进行条件过滤,符合过滤条件的才能继续留在流中
2》map:可以把流中的元素进行计算或转换
3》distinct:去除流中的重复元素
备注:distinct方法是依赖Object的equals和hashCode方法来判断是否是相同对象,所以需要重写equals方法
注意:为什么distinct重写了equals和hashCode依然不能实现去重,是因为默认是整个对象每个元素都相同时地址才一样
需要重写equals和hashCode方法对类中的某些属性不要求一样也认为对象是相同的
4》sorted:对流中的元素进行排序
分为有参和无参方法
无参:在比较的实体类上要实现Comparable接口,不然会报类型不匹配的异常
有参:正常匿名内部类
5》limit:可以设置流的最大长度,超出的部分将被抛弃
6》skip:跳过流中的前n个元素,返回剩下的元素
7》flatMap:map只能把一个对象转换成另一个对象来作为流中的元素。
而flatMap可以把一个对象转换成多个对象作为流中的元素
10.终结操作:
备注:对于stream流来说,必须存在终结操作才有意义
1》foreach:对流中的元素进行遍历操作,我们通过传入的参数去指定对遍历到的元素进行什么具体操作
2》count:可以用来获取当前流中元素的个数
3》min&max:可以用来获取流中的最值
4》collect:把当前流转换成一个集合 List集合、set集合、Map集合
他有独特的工具类去转,不用写匿名内部类的方式去转换 Collections
查找与匹配
5》anyMatch:可以用来判断是否有任意符合匹配条件的元素,结果为boolean类型
6》allMatch:可以用来判断是否都符合匹配条件,结果为boolean类型。如果都符合结果为true,否者结果为false
7》noneMatch:可以判断流中的元素是否都不符合匹配条件。如果都不符合结果为true,否则结果为false
8》finaAny:获取流中的任意一个元素。该方法没有办法保证获取的一定是流中的第一个元素
9》findFirst:获取流中的第一个元素
10》reduce归并:对流中的数据按照你指定的计算方式计算出一个结果。(缩减操作)
reduce的作用是把stream中的元素给组合起来,我们可以传入一个初始值,它会按照我们的计算方式依次拿流中的元素和初始化值
进行计算,计算结果再和后面的元素计算。
11.Optional:
解决问题:我们在编写代码的时候出现最多的就是空指针异常。所以在很多情况下我们需要做各种非空的判断
备注:常见的就是创建Optional对象,利用Optional对象的方法去解决空指针异常
1》Optional.ofNullable(对象);》把数据封装成一个Optional对象。无论传入的参数是否为null都不会出现问题
2》Optional.ifPresent(具体操作);》判断其内封装的数据是否为空,不为空时才会执行具体的消费代码,避免了空指针异常。
12.函数式接口:
定义:只有一个抽象方法的接口我们称之为函数接口。
JDK的函数式接口都加上@FunctionalInterface注解进行标识。但是无论是否加上该注解只要接口中只有一个抽象方法,
都是函数式接口。
备注:在前面学习的匿名内部类中,就用到了很多的函数式接口
常见函数式接口:
1》Consumer 消费接口:根据其中抽象方法的参数列表和返回值类型知道,我们可以在方法中对传入的参数进行消费。
2》Function 计算转换接口:根据其中抽象方法的参数列表和返回值类型知道,我们可以在方法中对传入的参数计算或转换,
把结果返回
3》Predicate 判断接口:根据其中抽象方法的参数列表和返回值类型知道,我们可以在方法中对传入的参数条件判断,
返回判断结果
4》Supplier 生产型接口:根据其中抽象方法的参数列表和返回值类型知道,我们可以在方法中创建对象,把创建好的对象返回
13.高级用法
1》基本数据类型优化:我们之前用到的很多Stream的方法由于都使用了泛型。所以涉及到的参数和返回值都是引用数据类型
例如利用map将实体对象转换成Integer对象,之后对这个Integer对象进行计算,这里面就涉及到先将Integer对象拆箱成
int类型进行计算,之后再将int类型装箱成Integer类型,当数据量很大时,就不能忽略时间的消耗也是很大的,对此进行优化!
Stream还提供了很多专门针对基本数据类型的方法:mapToInt,mapToLong,mapToDouble,flatMapToInt,flatMapToDouble等
这样就可以省却装箱拆箱所消耗的时间。
2》并行流:当流中有大量元素时,我们可以使用并行流去提高操作的效率。其实并行流就是把任务分配给多个线程去完成。
如果我们自己去用代码实现的话其实会非常的复杂,并且要求你对并发编程有足够的理解和认识。而如果我们使用Stream流的话,
我们只需要修改一个方法的调用就可以使用并行流来帮我们实现,从而提高效率
parallel方法可以把串行流转换成并行流:stream.parallel() 在stream流后面加上.parallel()即可
或者对象.parallelStream() 效果与上面一样