Stream 是Java SE 8类库中新增的关键抽象,它被定义于 java.util.stream (这个包里有若干流类型:Stream<T> 代表对象引用流。
此外还有一系列特化流,如 IntStream,LongStream,DoubleStream等 ),Java 8 引入的的Stream主要用于取代部分Collection的操作,每个流代表一个值序列,流提供一系列常用的聚集操作,可以便捷的在它上面进行各种运算。
集合类库也提供了便捷的方式使我们可以以操作流的方式使用集合、数组以及其它数据结构;
①中间操作
②终端操作
①只能遍历一次:
数据流的从一头获取数据源,在流水线上依次对元素进行操作,当元素通过流水线,便无法再对其进行操作,可以重新在数据源获取一个新的数据流进行操作;
②采用内部迭代的方式:
对Collection进行处理,一般会使用?Iterator?遍历器的遍历方式,这是一种外部迭代;
而对于处理Stream,只要申明处理方式,处理过程由流对象自行完成,这是一种内部迭代,对于大量数据的迭代处理中,内部迭代比外部迭代要更加高效;
好了,上面 stream 的优点吹了那么多,stream 函数式的写法是很舒服,那么 steam 的效率到底怎样呢?
先说结论:
- 传统 iterator (for-loop) 比 stream(JDK8) 迭代性能要高,尤其在小数据量的情况下;
- 在多核情景下,对于大数据量的处理,parallel stream 可以有比 iterator 更高的迭代处理效率;
我分别对一个随机数列 List (数量从 10 到 10000000)进行映射、过滤、排序、规约统计、字符串转化场景下,对使用 stream 和 iterator 实现的运行效率进行了统计,。
测试环境如下:
System:Ubuntu 16.04 xenial
CPU:Intel Core i7-8550U
RAM:16GB
JDK version:1.8.0\_151
JVM:HotSpot(TM) 64-Bit Server VM (build 25.151-b12, mixed mode)
JVM Settings:
-Xms1024m
-Xmx6144m
-XX:MaxMetaspaceSize=512m
-XX:ReservedCodeCacheSize=1024m
-XX:+UseConcMarkSweepGC
-XX:SoftRefLRUPolicyMSPerMB=100
1. 映射处理测试
把一个随机数列(List<Integer>)中的每一个元素自增1后,重新组装为一个新的 List<Integer>,测试的随机数列容量从 10 - 10000000,跑10次取平均时间;
`//stream`
`List<Integer>?result?=?list.stream()`
`.mapToInt(x?->?x)`
`.map(x?->?++x)`
`.boxed()`
`.collect(Collectors.toCollection(ArrayList::new));`
`//iterator`
`List<Integer>?result?=?new?ArrayList<>();`
`for(Integer?e?:?list){`
`result.add(++e);`
`}`
`//parallel?stream`
`List<Integer>?result?=?list.parallelStream()`
`.mapToInt(x?->?x)`
`.map(x?->?++x)`
`.boxed()`
`.collect(Collectors.toCollection(ArrayList::new));`
2. 过滤处理测试
取出一个随机数列(List<Integer>)中的大于 200 的元素,并组装为一个新的 List<Integer>,测试的随机数列容量从 10 - 10000000,跑10次取平均时间;
`//stream`
`List<Integer>?result?=?list.stream()`
`.mapToInt(x?->?x)`
`.filter(x?->?x?>?200)`
`.boxed()`
`.collect(Collectors.toCollection(ArrayList::new));`
`//iterator`
`List<Integer>?result?=?new?ArrayList<>(list.size());`
`for(Integer?e?:?list){`
`if(e?>?200){`
`result.add(e);`
`}`
`}`
`//parallel?stream`
`List<Integer>?result?=?list.parallelStream()`
`.mapToInt(x?->?x)`
`.filter(x?->?x?>?200)`
`.boxed()`
`.collect(Collectors.toCollection(ArrayList::new));`
3. 自然排序测试
对一个随机数列(List<Integer>)进行自然排序,并组装为一个新的 List<Integer>,iterator 使用的是 Collections # sort API(使用归并排序算法实现),测试的随机数列容量从 10 - 10000000,跑10次取平均时间;
`//stream`
`List<Integer>?result?=?list.stream()`
`.mapToInt(x->x)`
`.sorted()`
`.boxed()`
`.collect(Collectors.toCollection(ArrayList::new));`
`//iterator`
`List<Integer>?result?=?new?ArrayList<>(list);`
`Collections.sort(result);`
`//parallel?stream`
`List<Integer>?result?=?list.parallelStream()`
`.mapToInt(x->x)`
`.sorted()`
`.boxed()`
`.collect(Collectors.toCollection(ArrayList::new));`
4. 归约统计测试
获取一个随机数列(List<Integer>)的最大值,测试的随机数列容量从 10 - 10000000,跑10次取平均时间;
`//stream`
`int?max?=?list.stream()`
`.mapToInt(x?->?x)`
`.max()`
`.getAsInt();`
`//iterator`
`int?max?=?-1;`
`for(Integer?e?:?list){`
`if(e?>?max){`
`max?=?e;`
`}`
`}`
`//parallel?stream`
`int?max?=?list.parallelStream()`
`.mapToInt(x?->?x)`
`.max()`
`.getAsInt();`
5. 字符串拼接测试
获取一个随机数列(List<Integer>)各个元素使用“,”分隔的字符串,测试的随机数列容量从 10 - 10000000,跑10次取平均时间;
`//stream`
`String?result?=?list.stream().map(String::valueOf).collect(Collectors.joining(","));`
`//iterator`
`StringBuilder?builder?=?new?StringBuilder();`
`for(Integer?e?:?list){`
`builder.append(e).append(",");`
`}`
`String?result?=?builder.length()?==?0???""?:?builder.substring(0,builder.length()?-?1);`
`//parallel?stream`
`String?result?=?list.stream().map(String::valueOf).collect(Collectors.joining(","));`
6. 混合操作测试
对一个随机数列(List<Integer>)进行去空值,除重,映射,过滤,并组装为一个新的 List<Integer>,测试的随机数列容量从 10 - 10000000,跑10次取平均时间;
`//stream`
`List<Integer>?result?=?list.stream()`
`.filter(Objects::nonNull)`
`.mapToInt(x?->?x?+?1)`
`.filter(x?->?x?>?200)`
`.distinct()`
`.boxed()`
`.collect(Collectors.toCollection(ArrayList::new));`
`//iterator`
`HashSet<Integer>?set??=?new?HashSet<>(list.size());`
`for(Integer?e?:?list){`
`if(e?!=?null?&&?e?>?200){`
`set.add(e?+?1);`
`}`
`}`
`List<Integer>?result?=?new?ArrayList<>(set);`
`//parallel?stream`
`List<Integer>?result?=?list.parallelStream()`
`.filter(Objects::nonNull)`
`.mapToInt(x?->?x?+?1)`
`.filter(x?->?x?>?200)`
`.distinct()`
`.boxed()`
`.collect(Collectors.toCollection(ArrayList::new));`
实验结果总结
从以上的实验来看,可以总结处以下几点:
使用 Stream 的建议
源于:blog.csdn.net/Al\_assad/article/details/82356606
折叠式卡片布局在PC版网站中可能不常见,但是在手机版,小屏幕的网页浏览会大发...
1、纯工具操作步骤,懂代码更容易 划线就是不符合国人的审美观念,看着就别扭,...
简介: 6月4日,以“开启分布式云新时代”为主题2021云边协同大会在北京举行,本...
1.先瞧瞧效果: 2.代码是这样的: img src=images/circle.png alt= id=circle/@m...
在默认情况之下,如果在Canvas之中将某个物体(源)绘制在另一个物体(目标)之...
本文没有咬文嚼字的地方,只是一个配色技巧的分享,十分简单,简单到流泪,但或...
背景 在公司参与一个原生APP和h5混合开发的项目,本人在项目中负责h5部分,现将...
一、虽然有的属性是boolean类型,但仍旧建议按照XHTML书写(属性名=属性值)格式...
前言 Canvas绘制多变形非常简单,只要懂得Canvas路径 + 简单的初中数学知识即可...
作者:Joe Seifi 译者:前端小智 移动: https://mp.weixin.qq.com/s/p5... 有梦...