Java8的Stream流详解「建议收藏」

Java8的Stream流详解「建议收藏」首先,Stream流有一些特性:Stream流不是一种数据结构,不保存数据,它只是在原数据集上定义了一组操作。这些操作是惰性的,即每当访问到流中的一个元素,才会在此元素上执行这一系列操作。Stream不保存数据,故每个Stream流只能使用一次。关于应用在Stream流上的操作,可以分成两种:Intermediate(中间操作)和Terminal(终止操作)。中间操作的返回结果都是…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

首先,Stream流有一些特性:

  1. Stream流不是一种数据结构,不保存数据,它只是在原数据集上定义了一组操作。
  2. 这些操作是惰性的,即每当访问到流中的一个元素,才会在此元素上执行这一系列操作。
  3. Stream不保存数据,故每个Stream流只能使用一次。

关于应用在Stream流上的操作,可以分成两种:Intermediate(中间操作)和Terminal(终止操作)。中间操作的返回结果都是Stream,故可以多个中间操作叠加;终止操作用于返回我们最终需要的数据,只能有一个终止操作。至于哪些方法是中间操作,哪些方法是终止操作,我们一会儿再说。

使用Stream流,可以清楚地知道我们要对一个数据集做何种操作,可读性强。而且可以很轻松地获取并行化Stream流,不用自己编写多线程代码,可以让我们更加专注于业务逻辑。

接下来看一下Stream流的接口继承关系:
Java8的Stream流详解「建议收藏」

基础接口BaseStream<T, S extends BaseStream<T, S>>包含如下方法:

Iterator<T> iterator();

Spliterator<T> spliterator();

boolean isParallel(); //判断是否是并行化流

S sequential(); //将流串行化

S parallel(); //将流并行化

S unordered();  //解除有序流的顺序限制,发挥并行处理的性能优势

S onClose(Runnable closeHandler);

void close();

默认情况下,从有序集合、生成器、迭代器产生的流或者通过调用Stream.sorted产生的流都是有序流,有序流在并行处理时会在处理完成之后恢复原顺序。unordered()方法可以解除有序流的顺序限制,更好地发挥并行处理的性能优势,例如distinct将保存任意一个唯一元素而不是第一个,limit将保留任意n个元素而不是前n个。

BaseStream的四个子接口方法都差不多,只是IntStream、LongStream、DoubleStream直接存储基本类型,可以避免自动装/拆箱,效率会更高一些。下面以Stream为例,将接口的方法分类讲解一下。

一、 流的生成方法

  1. Collection接口的stream()或parallelStream()方法
  2. 静态的Stream.of()、Stream.empty()方法
  3. Arrays.stream(array, from, to)
  4. 静态的Stream.generate()方法生成无限流,接受一个不包含引元的函数
  5. 静态的Stream.iterate()方法生成无限流,接受一个种子值以及一个迭代函数
  6. Pattern接口的splitAsStream(input)方法
  7. 静态的Files.lines(path)、Files.lines(path, charSet)方法
  8. 静态的Stream.concat()方法将两个流连接起来
  9. ……

注意,无限流的存在,侧面说明了流是惰性的,即每当用到一个元素时,才会在这个元素上执行这一系列操作。

二、 流的Intermediate方法(中间操作)

  1. filter(Predicate)
    将结果为false的元素过滤掉
  2. map(fun)
    转换元素的值,可以用方法引元或者lambda表达式
  3. flatMap(fun)
    若元素是流,将流摊平为正常元素,再进行元素转换
  4. limit(n)
    保留前n个元素
  5. skip(n)
    跳过前n个元素
  6. distinct()
    剔除重复元素
  7. sorted()
    将Comparable元素的流排序
  8. sorted(Comparator)
    将流元素按Comparator排序
  9. peek(fun)
    流不变,但会把每个元素传入fun执行,可以用作调试

三、 流的Terminal方法(终结操作)

  • 约简操作

    1. max(Comparator)
    2. min(Comparator)
    3. count()
    4. findFirst()
      返回第一个元素
    5. findAny()
      返回任意元素
    6. anyMatch(Predicate)
      任意元素匹配时返回true
    7. allMatch(Predicate)
      所有元素匹配时返回true
    8. noneMatch(Predicate)
      没有元素匹配时返回true
    9. reduce(fun)
      从流中计算某个值,接受一个二元函数作为累积器,从前两个元素开始持续应用它,累积器的中间结果作为第一个参数,流元素作为第二个参数
    10. reduce(a, fun)
      a为幺元值,作为累积器的起点
    11. reduce(a, fun1, fun2)
      与二元变形类似,并发操作中,当累积器的第一个参数与第二个参数都为流元素类型时,可以对各个中间结果也应用累积器进行合并,但是当累积器的第一个参数不是流元素类型而是类型T的时候,各个中间结果也为类型T,需要fun2来将各个中间结果进行合并
  • 收集操作

    1. iterator()
    2. forEach(fun)
    3. forEachOrdered(fun)
      可以应用在并行流上以保持元素顺序
    4. toArray()
    5. toArray(T[] :: new)
      返回正确的元素类型
    6. collect(Collector)
    7. collect(fun1, fun2, fun3)
      fun1转换流元素;fun2为累积器,将fun1的转换结果累积起来;fun3为组合器,将并行处理过程中累积器的各个结果组合起来

然后再看一下有哪些Collector收集器:

  1. Collectors.toList()
  2. Collectors.toSet()
  3. Collectors.toCollection(集合的构造器引用)
  4. Collectors.joining()、Collectors.joining(delimiter)、Collectors.joining(delimiter、prefix、suffix)
    字符串元素连接
  5. Collectors.summarizingInt/Long/Double(ToInt/Long/DoubleFunction)
    产生Int/Long/DoubleSummaryStatistics对象,它有getCount、getSum、getMax、getMin方法,注意在没有元素时,getMax和getMin返回Integer/Long/Double.MAX/MIN_VALUE
  6. Collectors.toMap(fun1, fun2)/toConcurrentMap
    两个fun用来产生键和值,若值为元素本身,则fun2为Function.identity()
  7. Collectors.toMap(fun1, fun2, fun3)/toConcurrentMap
    fun3用于解决键冲突,例如(oldValue, newValue) -> oldValue,有冲突时保留原值
  8. Collectors.toMap(fun1, fun2, fun3, fun4)/toConcurrentMap
    默认返回HashMap或ConcurrentHashMap,fun4可以指定返回的Map类型,为对应的构造器引元
  9. Collectors.groupingBy(fun)/groupingByConcurrent(fun)
    fun是分类函数,生成Map,键是fun函数结果,值是具有相同fun函数结果元素的列表
  10. Collectors.partitioningBy(fun)
    键是true/false,当fun是断言函数时用此方法,比groupingBy(fun)更高效
  11. Collectors.groupingBy(fun1, fun2)
    fun2为下游收集器,可以将列表转换成其他形式,例如toSet()、counting()、summingInt/Long/Double(fun)、maxBy(Comparator)、minBy(Comparator)、mapping(fun1, fun2)(fun1为转换函数,fun2为下游收集器)

最后提一下基本类型流,与对象流的不同点如下:

  1. IntStream和LongStream有range(start, end)和rangeClosed(start, end)方法,可以生成步长为1的整数范围,前者不包括end,后者包括end
  2. toArray方法将返回基本类型数组
  3. 具有sum、average、max、min方法
  4. summaryStatics()方法会产生类型为Int/Long/DoubleSummaryStatistics的对象
  5. 可以使用Random类的ints、longs、doubles方法产生随机数构成的流
  6. 对象流转换为基本类型流:mapToInt()、mapToLong()、mapToDouble()
  7. 基本类型流转换为对象流:boxed()

以上就是对Java8的Stream流的介绍,日后在实践中有新的体会之后还会再来补充……

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/185323.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • java保留小数_Java保留两位小数的几种做法「建议收藏」

    java保留小数_Java保留两位小数的几种做法「建议收藏」页面或界面上展示的数据保留小数点后两位。为了达到这样的展示效果,本文列举了几个方法:1.使用java.math.BigDecimal2.使用java.text.DecimalFormat3.使用java.text.NumberFormat4.使用java.util.Formatter5.使用String.format……另外可以自己实现或者借用封装好的类库来实现,在这篇文章中…

  • PHP实现图片的等比缩放和Logo水印功能示例

    PHP实现图片的等比缩放和Logo水印功能示例

    2021年10月25日
  • c语言背包问题(动态规划解法)

    c语言背包问题(动态规划解法)题目描述:有若干个物品要装进背包,并且每个物品有各自的价值,物品的数量、价值以及背包的容量由用户输入,求背包内能够存入的最大价值为多少,并且求出此时放入了哪些物品输入格式:第一行输入物品的容量r和物品个数n第二行输入每个物品的重量第三行输入每个物品的价值输出格式:第一行输出背包中能够存储的最大价值第二行输出此时背包中的物品编号思路分析:可以把这个问题看成是一个二维数组,行是物品编号,列是背包容量,若物品编号为2,背包容量为4,代表的则是当背包容量为..

  • eBPF 学习路径总结「建议收藏」

    eBPF 学习路径总结「建议收藏」BPF学习路径总结•Feiskyhttps://feisky.xyz/posts/2021-01-06-ebpf-learn-path/目录1.为什么要学习BPF2.BPF应该怎么学习2.1BPF书籍2.2BPF学习样例3.BPF资料汇总3.1介绍系列3.2深入系列3.3Linux资源作者简介:狄卫华,趣头条资深架构师,主要关注云原生相关领域,目前聚焦在BPF技术及实践.1.为什么要学习BPF可以先从ebpf.i.

  • vue单页面应用的原理

    vue单页面应用的原理通常的url地址由什么构成呢:协议名域名端口号路径参数哈希值比如:http://www.itcast.cn:80/home/index?name=zs#absdklfajdf当哈希值改变(哈希值就是:#absdklfajdf),页面不会发生跳转,单页面应用就是利用了这一点:单页面应用因为只有一个页面,所以页面不能发生跳转,但是,我们又需要根据url地址来展示不同的组件…

  • 【mybatis系列】自定义实现拦截器插件Interceptor

    【mybatis系列】自定义实现拦截器插件Interceptor目录类型规则介绍intercept(Invocationinvocation)plugin(Objecttarget)setProperties(Propertiesproperties)实战首先熟悉一下Mybatis的执行过程,如下图:拦截器应用场景:类型先说明Mybatis中可以被拦截的类型具体有以下四种:1.Executor:拦截执行器的方法。2.ParameterHandler:拦截参数的处理。3.ResultHandler:拦截结果集的处理。4.StatementHandl

    2022年10月25日

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号