Stream 串行流 原理

Stream 为什么会出现?

Stream 出现之前,遍历一个集合最传统的做法大概是用 Iterator,或者 for 循环。这种两种方式都属于外部迭代,然而外部迭代存在着一些问题。

  • 开发者需要自己手写迭代的逻辑,虽然大部分场景迭代逻辑都是每个元素遍历一次。

  • 如果存在像排序这样的有状态的中间操作,不得不进行多次迭代。

  • 多次迭代会增加临时变量,从而导致内存的浪费。

虽然 Java 5 引入的 foreach 解决了部分问题,但也引入了新的问题。

  • foreach 遍历不能对元素进行赋值操作

  • 遍历的时候,只有当前被遍历的元素可见,其他不可见

随着大数据的兴起,传统的遍历方式已经无法满足开发者的需求。

就像小作坊发展到一定程度要变成大工厂才能满足市场需求一样。大工厂和小作坊除了规模变大、工人不多之外,最大的区别就是多了流水线。流水线可以将工人们更高效的组织起来,使得生产力有质的飞跃。

所以不安于现状的开发者们想要开发一种更便捷,更实用的特性。

  • 它可以像流水线一样来处理数据

  • 它应该兼容常用的集合

  • 它的编码应该更简洁

  • 它应该具有更高的可读性

  • 它可以提供对数据集合的常规操作

  • 它可以拼装不同的操作

经过不懈的能力,Stream 就诞生了。加上 lambda 表达式的加成,简直是如虎添翼。

你可以用 Stream 干什么?

下面以简单的需求为例,看一下 Stream 的优势:

从一列单词中选出以字母a开头的单词,按字母排序后返回前3个。

传统实现方式

List<String> list = Lists.newArrayList("are", "where", "advance", "anvato", "java", "abc");

List<String> tempList = Lists.newArrayList();

List<String> result = Lists.newArrayList();

for( int i = 0; i < list.size(); i++) {

    if (list.get(i).startsWith("a"))

        tempList.add(list.get(i));

}

tempList.sort(Comparator.naturalOrder());

result = tempList.subList(0,3);

Stream实现方式

List<String> list = Arrays.asList("are", "where", "anvato", "java", "abc");

List<String> result =

    list.stream()                //定义输入源,得到Stage0 Head节点(流)

      .filter(s -> s.startsWith("a"))   //定义中间操作,得到Stage1 StatelessOp节点(流) 

      .sorted()                //定义中间操作,得到Stage2 StatefulOp节点(流),SortedOps.OfRef实例

      .limit(3)                //定义中间操作,得到Stage3 StatefulOp节点(流),SliceOps的StatefulOp实例

      .collect(Collectors.toList());    //定义终端操作, TerminalOp节点(流),ReduceOp实例

Stream 是怎么实现的?

需要解决的问题:

  • 如何定义流水线?

  • 原料如何流入?

  • 如何让流水线上的工人将处理过的原料交给下一个工人?

  • 流水线何时开始运行?

  • 流水线何时结束运行?

总观全局

Stream 处理数据的过程可以类别成工厂的流水线。数据可以看做流水线上的原料,对数据的操作可以看做流水线上的工人对原料的操作。

事实上 Stream 只是一个接口,并没有操作的缺省实现。最主要的实现是 ReferencePipeline,而 ReferencePipeline 继承自 AbstractPipeline ,AbstractPipeline 实现了 BaseStream 接口并实现了它的方法。但 ReferencePipeline 仍然是一个抽象类,因为它并没有实现所有的抽象方法,比如 AbstractPipeline 中的 opWrapSink()抽象方法,该方法是由具体的中间操作和终端操作来实现的 。ReferencePipeline内部定义了三个静态内部类,分别是:Head, StatelessOp, StatefulOp,但只有 Head 不再是抽象类。

<

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值