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

news/2024/11/30 18:54:01/

1 引言

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

2 流简介

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

2.1 支持数据处理操作

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

2.2 源

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

List<Integer> list = Arrays.asList(111,222,333);
Stream<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的前两个商品的名字。

首先是商品类的定义:

public class Goods {private final String Name;private final Integer Volume;public Goods(String name, Integer volume) {Name = name;Volume = volume;}public String getName() {return Name;}public Integer getVolume() {return Volume;}
}

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

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

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

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

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

4 流处理的特性

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

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

import org.springframework.util.Assert;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class StreamCharacteristic {public void test1(){List<Integer> list = Arrays.asList(1,2,2,5,6,9);list.stream().distinct();System.out.println(list.size());}public void test2(){List<String> list = Arrays.asList("wms", "KA", "5.0");Stream<String> stream = list.stream();stream.forEach(System.out::println);stream.forEach(System.out::println);}
}

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


http://www.ppmy.cn/news/805816.html

相关文章

wps只要拼音不要汉字

下面与大家分享一下wps怎么只要拼音不要汉字的教程吧。 1.打开文档&#xff0c;进入页面&#xff0c;选中文字内容。 2.在开始菜单栏中&#xff0c;单击拼音指南&#xff0c;弹出窗口。 3.删除文字并输入空格&#xff0c;完成后&#xff0c;设置字体、字号、偏移量等&#xff0…

wps文字表格制作拼音田字格模板_最新用WPS表格快速制作拼音田字格的方法

最新精品资料推荐 …………………………………………………… ………………………………………………………… 最新精品资料推荐 …………………………………………………… 1 用 WPS 表格快速制作拼音田字格的方法 打开 WPS 表格&#xff0c; 选定全部单元格。 然后单击 “ 格…

WPS 2007如何获得漂亮的拼音效果

语文试卷中一般都会有根据拼音写汉字的题目&#xff0c;利用WPS文字2007可以很轻松的实现这个要求。首先在文档中正常输入需要注音的汉字&#xff0c;例如“暖风熏得游人醉&#xff0c;直把杭州作汴州”&#xff0c;选中这些诗句&#xff0c;依次选择“格式”→“中文版本”→“…

WPS Word中怎么打出拼音和声调让别人懂的这个字怎么读

有些字上面都会带有拼音&#xff0c;这是为了让别人懂的这个字怎么读&#xff0c;你是否好奇他是怎么做到的呢&#xff1f;在WPS Word中如何打出拼音和声调呢&#xff1f;其实很简单的WPS中打出拼音和声调的方法有两种&#xff0c;一是利用输入法的软键盘&#xff0c;二是在Wor…

WPS不能输入中文的解决方法

已经在linux上安装了wps好几天了一直没用&#xff0c;今天用它来编辑文档时发现竟然不能用中文。相应的解决方案如下&#xff1a; 我的系统为 Centos7.5 [SangHuiHui ~]$ cat /etc/redhat-release CentOS Linux release 7.5.1804 (Core)原因&#xff1a;不能中文输入的原因是…

wps小写金额转大写快捷键_WPS轻松办公—将数字转换中文大写的两种方法

大家好&#xff0c;我们在运用WPS文字或者Word软件进行日常办公的时候&#xff0c;常常需要将数字转换为中文大写的汉字&#xff0c;或者是财会人员会直接用拼音输入数字的大写汉字&#xff0c;这样不仅非常麻烦&#xff0c;而且效率也会很低&#xff0c;今天我们就来教大家如何…

WPS下搜狗输入法不能输入中文

问题&#xff1a;WPS下搜狗输入法不能输入中文 原因&#xff1a;环境变量未正确设置 方法&#xff1a;—————————————————— &#xff08;1&#xff09;word部分 $ vi /usr/bin/wps 在第一行 #!/bin/bash 下添加&#xff1a; export XMODIFIERS"imfcitx&q…

WPS拼音指南乱用;切换域代码乱用

先上图&#xff1b; 看到上面这个图 第一个想到的是&#xff0c;拼音填空可用在word中自由&#xff1b; 第二个想到的是&#xff0c;中文&#xff0c;拼音&#xff0c;英语&#xff0c;可用三合一行显示了。记住是三合一行&#xff0c;和三行还是有区别的&#xff0c;三行的…