java 8 Stream
发布时间:2024年01月22日
目录
1. Stream概述
1.1 基本概念
1.2 Stream特性
2. Stream流的创建
3. Stream API分类
3.1 中间操作(返回一个新的Stream)
3.2 终端操作(返回一个新的数据集或值)
4. Collector收集器
参考
1. Stream概述
1.1 基本概念
- Stream是java 8引入的特性,与Lambda表达式配合使用时,为我们操作集合(Collection)提供了极大的便利
- Stream把要处理的数据集看作一种流,然后借助Stream API对流中的元素进行操作,对流中元素的操作主要分为两种:中间操作(intermediate operation)和终端操作(terminal operation)。中间操作的返回结果是Stream,一次可以有多个中间操作叠加;而终端操作会返回经过操作后的最终数据,一次只能有一个终端操作
- 为了执行一次计算,多个Stream操作组成一个Stream流水线(pipeline),流水线中包含一个数据源、若干个中间操作和一个终端操作
- Stream和IntStream、LongStream、DoubleStream都是BaseStream接口的子接口,这四个子接口中的方法都差不多,区别在于IntStream、LongStream、DoubleStream直接存储基本数据类型。Stream可以通过mapToInt()/mapToLong()/mapToDouble()方法转换成另外三个Stream
1.2 Stream特性
- Stream不是一种数据结构,它不保存数据,而是根据特定的规则对原数据集进行计算/操作
- Stream不改变数据源,通常情况下会通过终端操作产出一个新的数据集或值
- Stream是惰性(lazy)的,只有当终端操作被初始化后,对数据源的计算操作才会执行
2. Stream流的创建
- Collection接口的stream()或parallelStream()方法(在实际项目开发中很常见)
- 静态的Stream.of()、Stream.empty()方法
- 静态的Stream.iterate()方法生成无限流,接受一个种子值以及一个迭代函数
- 静态的Stream.generate()方法生成无限流
- 静态的Arrays.stream()方法
- 。。。
3. Stream API分类
把Stream中的常用方法按中间操作和终端操作分成两大类。
3.1 中间操作(返回一个新的Stream)
- filter()方法:把不符合过滤条件的元素过滤掉,即保留结果为true的元素、排除结果为false的元素
- map()方法:把一个流中的元素按照特定的映射规则进行映射
- sorted()/sorted(Comparator)方法:把流中元素按照自然序(适合包装类和String类元素)/给定的比较器排序(适合实体类型元素)
- peek()方法:查看每个元素在经过Stream流水线中某个步骤时的状态,可以用来调试
- distinct()方法:去除重复元素
- limit(n)方法:保留前n个元素
- skip(n)方法:跳过前n个元素
- mapToInt()/mapToLong()/mapToDouble()方法:把Stream流转换成相应的基本类型流
3.2 终端操作(返回一个新的数据集或值)
- forEach()方法:遍历流中的元素,利用Lambda表达式操作每一个元素,此方法会按特定规则改变流中的每个元素
- findFirst()/findAny()方法:查找流中的第一个/任意一个(如果是顺序流,默认返回第一个)元素
- anyMatch()/allMatch()/noneMatch()方法:判断流中是否有符合条件的元素/流中元素是否都符合条件/流中元素是否都不符合条件,返回true/false
- min()/max()/count()方法:统计流中元素的最值、个数
- reduce()方法:归约,即缩减,把流中的元素缩减成一个值返回,能实现对流中元素的求和、求乘积、求最值操作
- reduce(func)方法:接受一个二元函数作为累积器,从前两个元素开始持续应用它,累积器的中间结果作为第一个参数,流元素作为第二个参数。返回Optional类型元素
- reduce(a, func)方法:与上一个方法类似,多出来的参数a是累积器的起点,返回与a同类型元素
- collect()方法(在实际项目开发中很常见):对经过Stream流水线计算操作后还留在流中的元素进行搜集操作,常和Collector收集器搭配使用
4. Collector收集器
- Collectors.toList():把流中元素保存在List列表中
- Collectors.toSet():把流中元素保存在Set集合中、
- Collectors.toMap():把流中元素保存在Map哈希表中,进一步可分为以下三类方法:
- Collectors.toMap/toConcurrentMap(func1, func2):两个func分别用来产生键和值,若产生键冲突,报"duplicate key ..."异常
- Collectors.toMap/toConcurrentMap(func1, func2, func3):func1、func2还是用来产生键和值,func3用于解决键冲突,例如(key1, key2) -> key2,表示有冲突时保留后者(即最新版本)的kv值
- Collectors.toMap/toConcurrentMap(func1, func2, func3, func4):返回的Map默认是HashMap/ConcurrentHashMap,func4用于指定返回Map的具体类型,可以用对应的构造器引用表示,如HashMap::new
- 对于上述几个方法,若值为元素本身,则func2可以写成形如 t -> t 的Lambda表达式形式,也可以写成Function.identity()。关于Function.identity()的具体介绍,可以参考以下文章:https://stackoverflow.com/questions/28032827/java-8-lambdas-function-identity-or-t-t、https://www.jianshu.com/p/cd694d2d8be5
- Collectors.toCollection(Collection):把流中元素保存在指定的集合中,形参是集合的构造器引用
- Collectors.groupingBy/groupingByConcurrent(func):func是分类函数,生成Map,键是func函数结果,值是具有相同func函数结果的元素的列表
- Collectors.groupingBy(func1, func2):func2是下游收集器,可以把默认的List列表转换成其他形式,如toSet()、counting()、summingInt/Long/Double(func)、maxBy(Comparator)、minBy(Comparator)、mapping(func1, func2)(func1是转换函数,func2是下游收集器)等
- Collectors.partitioningBy(func):键是true/false,当func是断言函数(即返回值是boolean类型)时,此方法比groupingBy(func)更高效
- Collectors.joining()、Collectors.joining(delimiter)、Collectors.joining(delimiter, prefix, suffix):字符串元素连接
参考
- https://blog.csdn.net/mu_wind/article/details/109516995
- https://blog.csdn.net/lixiaobuaa/article/details/81099838
文章来源:https://blog.csdn.net/weixin_42108602/article/details/135736725
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:chenni525@qq.com进行投诉反馈,一经查实,立即删除!