聊一聊Java中的Steam流 | 京东物流技术团队

1 引言

在我们的日常编程任务中,对于集合的制造和处理是必不可少的。当我们需要对于集合进行分组或查找的操作时,需要用迭代器对于集合进行操作,而当我们需要处理的数据量很大的时候,为了提高性能,就需要使用到并行处理,这样的处理方式是很复杂的。流可以帮助开发者节约宝贵的时间,让以上的事情变得轻松。

2 流简介

流到底是什么呢?简要的定义为“从支持数据处理操作的源生成的元素序列”,接下来对于这个定义进行简要分析。

2.1 支持数据处理操作

流的数据处理操作和数据库的可以声明式的指定分组或查找等功能支持类似,和函数式编程的思想一致,如filter、map、reduce、find、match、sort等操作,这些流操作可以串行执行,也可以并行执行。

2.2 源

流会使用一个提供数据的源,可以通过三种方式来创建对象流,一种是由集合对象创建流:

1List<Integer> list = Arrays.asList(111,222,333); 2Stream<Integer> stream = list.stream();

一种是由数组创建流:

IntStream stream = Arrays.stream(new int(){111,222,333});

一种是由静态方法Stream.of()创建流,底层还是Arrays.stream():

Stream<Integer> stream = Stream.of(111, 222, 333);

Stream stream = Stream.of(111, 222, 333);

从有序集合生成流时会保留原有的顺序。由列表生成的流,其元素顺序与列表一致。
还有两种特殊的流:

  • 空流:Stream.empty()
  • 无限流:Stream.genarate()

2.3 元素序列

流也可以和集合一样访问包含特定的元素类型的一组有序值,但是它们的主要目的不一样,集合的主要目的是在于存储和访问元素,流的主要目的在于表达计算。

3 流的思想

流式思想和生产中的流水线具有异曲同工之妙,很多流模型都会返回一个流,这些模型都只负责它所需要做的事情,并不需要格外的内存空间来存储处理的结果。这些流模型可以被链接起来形成一个大的流水线,我们在这个过程中不关注中间步骤的数据被如何处理,只需要使用整个流水线处理后的结果。接下来的代码可以体现这种思想,代码中以商品为例,我们要筛选出商品中体积大于200的前两个商品的名字。

首先是商品类的定义:

1public class Goods { 2 private final String Name; 3 private final Integer Volume; 4 5 public Goods(String name, Integer volume) { 6 Name = name; 7 Volume = volume; 8 } 9 public String getName() { 10 return Name; 11 } 12 public Integer getVolume() { 13 return Volume; 14 } 15}

接下来是商品集合的定义:

1List<Goods> goods = Arrays.asList(new Goods("土豆",10), 2new Goods("冰箱",900),new Goods("办公椅",300));

接下来获取我们想要的结果:

1List<String> twofoods = goods.stream()//获取流 2 .filter(goods1 -> goods1.getVolume()>200)//筛选商品体积大于200的 3 .map(Goods::getName)//获取商品名称 4 .limit(2)//筛选头两个商品 5 .collect(Collectors.toList());//将结果保存在list中

这样看来,通过流来处理我们的特定需求,是不是比使用集合的迭代要方便很多呢?

4 流处理的特性

  • 不存储数据
  • 不会改变数据源
  • 只可被使用一次

这里我们使用一个测试类StreamCharacteristic来验证流处理的以上特性:

1import org.springframework.util.Assert; 2import java.util.Arrays; 3import java.util.List; 4import java.util.stream.Collectors; 5import java.util.stream.Stream; 6public class StreamCharacteristic { 7 public void test1(){ 8 List<Integer> list = Arrays.asList(1,2,2,5,6,9); 9 list.stream().distinct(); 10 System.out.println(list.size()); 11 } 12 public void test2(){ 13 List<String> list = Arrays.asList("wms", "KA", "5.0"); 14 Stream<String> stream = list.stream(); 15 stream.forEach(System.out::println); 16 stream.forEach(System.out::println); 17 } 18}

test1()中的结果为6,尽管我们对于list对象所生成的Stream流做了去重操作distinct(),但是不影响数据源list。

test2()中调用了两次 stream.forEach方法来打印每一个单词,第二次调用时,抛出了一个“java.lang.IllegalStateException”异常:“stream has already been operated upon or closed”。这说明流不存储数据,遍历完后这个流已经被消费掉了,而且流不可以重复使用。

5 流操作与流的使用

将所有的流操作连接起来可以组合成一个管道,管道有两类操作:中间操作和终端操作。
StreamAPI常用的中间操作有:filter,map,limit,sorted,distinct。

StreamAPI常用的终端操作有:forEach,count,collect。

在使用流的时候,主要需要三个要素:一个用来执行查询的数据源,用来形成一条流的流水线的中间操作链,一个能够执行流水线并能生成结果的终端操作。

下图展示了流的整个操作流程:

6 总结

  • 流是从支持数据处理操作的源生成的元素序列
  • 流的思想类似于生产中的流水线
  • 流不存储数据,不改变数据源,只能被改变一次
  • 流的操作主要分为中间操作和终端操作两大类

作者:京东物流 王辰玮

来源:京东云开发者社区 自猿其说Tech

点赞
收藏

评论区

加载中...

相关推荐

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

Java日期时间API系列31

  时间戳是指格林威治时间1970年01月01日00时00分00秒起至现在的总毫秒数,是所有时间的基础,其他时间可以通过时间戳转换得到。Java中本来已经有相关获取时间戳的方法,Java8后增加新的类Instant等专用于处理时间戳问题。 1获取时间戳的方法和性能对比1.1获取时间戳方法Java8以前

Java8 新特性之流式数据处理

一.流式处理简介在我接触到java8流式处理的时候,我的第一感觉是流式处理让集合操作变得简洁了许多,通常我们需要多行代码才能完成的操作,借助于流式处理可以在一行中实现。比如我们希望对一个包含整数的集合中筛选出所有的偶数,并将其封装成为一个新的List返回,那么在java8之前,我们需要通过如下代码实现:List<Inte

Java 8新特性之Stream 概念

Java8中有两大最为重要的改变。第一个是Lambda表达式;另外一个则是StreamAPI(java.util.stream.\)。Stream是Java8中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用StreamAPI对集合数据进行操作,就类似于使用SQL执行

Twitter的分布式自增ID算法snowflake (Java版)

概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移

Java 8 stream 实战

概述平时工作用python的机会比较多,习惯了python函数式编程的简洁和优雅。切换到java后,对于数据处理的『冗长代码』还是有点不习惯的。有幸的是,Java8版本后,引入了Lambda表达式和流的新特性,当流和Lambda表达式结合起来一起使用时,因为流申明式处理数据集合的特点,可以让代码变得简洁易读。幸福感爆棚,有没有!本文主要列举一些