原文链接:https://blog.csdn.net/bluuusea/article/details/79967039

Stream类全路径为:java.util.stream.Stream
对Stream的描述,引用其他文章中觉得比较好的介绍:

Java 8 中的 Stream 是对集合(Collection)对象功能的增强,它专注于对集合对象进行各种非常便利、高效的聚合操作(aggregate operation),或者大批量数据操作 (bulk data operation)。Stream API 借助于同样新出现的 Lambda 表达式,极大的提高编程效率和程序可读性。
即Stream的原理:

这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。
集合有两种方式生成流:
- stream() − 为集合创建串行流。
- parallelStream() − 为集合创建并行流。

并发模式(parallelStream)能够充分利用多核处理器的优势,使用 fork/join 并行方式来拆分任务和加速处理过程。java中也提供了多种并行处理的方式,看到一片文章对各几种并行的方式性能进行了测试,可以参考下:java中几种并行方式的性能分析。

Stream的的中间操作(intermediate)和最终操作(terminal)都包含哪些方法可以从类结构中看到:

上面截图基本包含了Strram的所有方法。

中间操作(intermediate)主要有以下方法(此类型的方法返回的都是Stream对象):
map (mapToInt, flatMap 等)、 filter、 distinct、 sorted、 peek、 limit、 skip、 parallel、 sequential、 unordered

终端操作(terminal)主要有以下方法:
forEach、 forEachOrdered、 toArray、 reduce、 collect、 min、 max、 count、 anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 iterator

此处按照类结构(截图)中的方法的顺序(以下例子中使用了Lambda表达式及方法引用,不了解的请戳:Lambda介绍,方法引用),进行介绍:

filter:通过设置条件来过滤元素。
List<String> list = Arrays.asList("aaa","ddd","bbb","ccc","a2a","d2d","b2b","c2c","a3a","d3d","b3b","c3c");

list.stream()
.filter((s)->s.contains("a"))
.forEach(s -> System.out.println(s));
1
2
3
4
5
以上代码使用filter方法过滤出只包含”a”的元素,然后通过forEach将满足条件的元素遍历出来。输出如下:

aaa
a2a
a3a
map:就是将对应的元素使用给定方法进行转换。
list.stream()
.filter((s)->s.contains("a"))
.map((s)-> s + "---map")
.forEach(s -> System.out.println(s));
1
2
3
4
5
在filter的基础上,给每个元素后面添加字符串”—map”,输出如下:

aaa—map
a2a—map
a3a—map
mapToInt:和map方法进行一样的操作,但是转换函数必须返回int类型
mapToLong:和map方法进行一样的操作,但是转换函数必须返回long类型
mapToDouble:和map方法进行一样的操作,但是转换函数必须返回double类型
此处以mapToInt进行演示:
list.stream()
.filter((s)->s.contains("a"))
.mapToInt((s)-> s.hashCode())
.forEach(s -> System.out.println(s));
1
2
3
4
在filter的基础上,将每个元素转换为其hashCode。输出为:

96321
94864
94895
flatMap:如果流的元素为数组或者Collection,flatMap就是将每个Object[]元素或Collection<Object>元素都转换为Object元素,如下:
Stream<String[]> 转换为 Stream<String>
Stream<Set> 转换为 Stream<String>
Stream<List> 转换为 Stream<String>
Stream<List> 转换为 Stream<Object>
看下例子:

List<String[]> setList = new ArrayList<>();
setList.add(new String[]{"aa","bb"});
setList.add(new String[]{"cc","dd"});
setList.add(new String[]{"ee","ff"});
//使用map方法
setList.stream()
.map(s->Arrays.stream(s))
.forEach(s-> System.out.println("map==" + s));
//使用flatMap方法
setList.stream()
.flatMap(s->Arrays.stream(s))
.forEach(s-> System.out.println("flatMap==" + s));
1
2
3
4
5
6
7
8
9
10
11
12
输出如下:

map==java.util.stream.ReferencePipeline&Head@50040f0c
map==java.util.stream.ReferencePipeline&Head@2dda6444
map==java.util.stream.ReferencePipeline&Head@5e9f23b4
flatMap==aa
flatMap==bb
flatMap==cc
flatMap==dd
flatMap==ee
flatMap==ff
可以看出map就是将数组流直接返回,flatMap是将数组流中的每个元素都返回。flatMapToInt,flatMapToLong,flatMapToDouble类似,只不过返回的是对应的类型的流,此处不做演示。

distinct:将集合中的元素去重。
List<String> disList = Arrays.asList("aaa","ddd","bbb","ddd","aaa");
disList.stream()
.distinct()
.forEach(s-> System.out.println(s));
1
2
3
4
输出如下:

aaa
ddd
bbb
sorted:将集合中的元素排序。
List<Integer> integerList = Arrays.asList(1,2,3,4);
integerList.stream()
.sorted()
.forEach(s-> System.out.println(s));
1
2
3
4
输出如下:

1
2
3
4
可以按照自定义排序:

integerList.stream()
.sorted((s1,s2)->s2.compareTo(s1))
.forEach(s-> System.out.println(s));
1
2
3
输出如下:

4
3
2
1
peek:生成一个包含原Stream的所有元素的新Stream,同时会提供一个消费函数即引用的方法A,当Stream每个元素被消费的时候都会先执行新Stream给定的方法A。peek是中间操作,如果pee后没有最终操作,则peek不会执行。
integerList.stream()
.peek(s-> System.out.println("peek = "+s));
1
2
此时没有输出,代码改为:

integerList.stream()
.peek(s-> System.out.println("peek = "+s))
.forEach(s-> System.out.println("forEach = "+s));
1
2
3
输出如下:

peek = 1
forEach = 1
peek = 2
forEach = 2
peek = 3
forEach = 3
peek = 4
forEach = 4
limit:返回Stream的前n个元素。
integerList.stream()
.limit(1)
.forEach(s-> System.out.println(s));
1
2
3
输出为:

1
skip:删除Stream的前n个元素。
integerList.stream()
.skip(1)
.forEach(s-> System.out.println(s));
1
2
3
输出如下:

2
3
4
forEach:遍历Stream中的每个元素,前面每个例子都有使用,此处不再演示。
forEachOrdered:遍历Stream中的每个元素。
区别:
在串行流(stream)中没有区别,在并行流(parallelStream)中如果数据源是有序集合,forEachOrdered输出顺序与数据源中顺序一致,forEach则是乱序。
看下使用forEach:

integerList.stream()
.forEach(s-> System.out.println(s));
1
2
输出(多次测试,每次结果都不一样):

3
1
4
2
再看使用forEachOrdered:

integerList.parallelStream()
.forEachOrdered(s-> System.out.println(s));
1
2
输出(测试多次,每次都是这个结果,与integerList中的元素顺序一致):

2
1
3
4
toArray:将流转换为Object[]或者指定类型的数组。
Object[] array = integerList.stream().toArray();
String[] strArr = integerList.stream().toArray(String[]::new);
1
2
reduce:将集合中的每个元素聚合成一条数据。有三种情况:
reduce(BinaryOperator accumulator):此处需要一个参数,返回Optional对象:
Optional<Integer> reduce = integerList.stream().reduce((a, b) -> a + b);
1
reduce(T identity, BinaryOperator accumulator):此处需要两个参数,第一个参数为起始值,第二个参数为引用的方法。从起始值开始,每个元素执行一次引用的方法(方法引用的中的两个参数:第一个参数为上个元素执行方法引用的结果,第二个参数为当前元素)。
int integer = integerList.stream().reduce(5,(a, b) -> a + b);
System.out.println(integer);
1
2
输出为:

15
此例中使用起始值为5,对集合中每个元素求和,可以理解为:5+2+1+3+4=15。

reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner):此处需要三个参数。此方法用在并发流(parallelStream)中,启动多个子线程使用accumulator进行并行计算,最终使用combiner对子线程结果进行合并,返回identity类型的数据,看到有篇文章对这个解释比较清楚:java8中3个参数的reduce方法怎么理解?
collect:将流转换成集合或聚合元素。有两种情况。接受一个参数和接受三个参数(三个参数在并发流parallelStream中使用),此处介绍一个参数的情况,单个参数接受的参数类型为Collector,Collectors 类实现了很多归约操作,详见:java8之collector
List<Integer> collects = integerList.stream()
.filter(a -> a > 1)
.collect(Collectors.toList());
System.out.println(collects);
1
2
3
4
此处统计集合中大于1的元素并最终返回list。输出如下:

[2, 3, 4]
min:获取集合中最小值。
Integer min = integerList.stream()
.filter(a -> a > 1)
.min((Integer a, Integer b) -> a.compareTo(b))
.get();
System.out.println(min);
1
2
3
4
5
输出为:

2
max:获取集合中最大值。
Integer max = integerList.stream()
.filter(a -> a > 1)
.max((Integer a, Integer b) -> a.compareTo(b))
.get();
System.out.println(max);
1
2
3
4
5
输出为:

4
count:获取集合中元素个数
long count = integerList.stream()
.filter(a -> a > 1)
.count();
System.out.println(count);
1
2
3
4
输出为:

3
anyMatch: Stream 中任意一个元素符合传入的 predicate,返回 true
allMatch:Stream 中全部元素符合传入的 predicate,返回 true
noneMatch:Stream 中没有一个元素符合传入的 predicate,返回 true
boolean b = integerList.stream()
.anyMatch(s -> s > 0);
boolean b1 = integerList.stream()
.allMatch(s -> s > 0);
boolean b2 = integerList.stream()
.noneMatch(s -> s > 0);
System.out.println("anyMatch = " + b);
System.out.println("allMatch = " + b1);
System.out.println("noneMatch = " + b2);
1
2
3
4
5
6
7
8
9
输出:

anyMatch = true
allMatch = true
noneMatch = false
findFirst:如果数据源是有序集合,返回Stream 中第一个元素的Optional对象,如果是无序集合,则返回Stream 中任意一个元素的Optional对象。
Integer first = integerList.stream()
.findFirst()
.get();
System.out.println(first);
1
2
3
4
输出为:

2
findAny:返回Stream 中任意一个元素的Optional对象。
Integer any = integerList.stream()
.findAny()
.get();
System.out.println(any);
1
2
3
4
输出为:

2
Stream还有几个静态方法,返回都是Stream对象。
静态方法如下:builder(返回Builder对象)、empty、of、iterate、generate、concat。
builder:返回一个Builder对象,Builder对象在调用build()返回Stream对象。
empty:返回一个空的有序的Stream对象。
of:返回包含单个元素的有序的Stream对象。
iterate:返回一个无限元素的有序的Stream对象。需要两个参数,第一个参数为初始值,第二个参数为要引用的方法,然后会通过递归循环调用引用的方法。

Stream.iterate(2,s->s+s)
.limit(10)
.forEach(s-> System.out.println(s));
1
2
3
输出为:

2
4
8
16
32
64
128
256
512
1024
generate:返回一个无限元素的无序的的Stream对象。需要一个参数,参数为引用的方法,然后会通过循环调用引用的方法来生成元素,常用于生成常量Stream和随机元素Stream。
concat:将两个Stream连接成一个Stream。需要两个Stream作为参数,如果两个Stream都是有序的并且无论参数Stream是否是并行Stream,得到的都是有序的Stream。输出元素顺序为先输出第一个Stream的元素,然后输出第二个Stream的元素。当结果Stream关闭时候,两个参数Stream同时关闭。

Stream.concat(integerList.stream(),disList.stream())
.forEach(s-> System.out.println(s));
1
2
输出为:

2
1
3
4
11
aaa
ddd
33
bbb
ddd
aaa
————————————————
版权声明:本文为CSDN博主「昵称2019」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/bluuusea/article/details/79967039

JAVA8新特性--集合流操作Stream的更多相关文章

  1. Java8 新特性之集合操作Stream

    Java8 新特性之集合操作Stream Stream简介 Java 8引入了全新的Stream API.这里的Stream和I/O流不同,它更像具有Iterable的集合类,但行为和集合类又有所不同 ...

  2. Java8 新特性之Stream----java.util.stream

    这个包主要提供元素的streams函数操作,比如对collections的map,reduce. 例如: int sum = widgets.stream() .filter(b -> b.ge ...

  3. Java8新特性(1)—— Stream集合运算流入门学习

    废话,写在前面 好久没写博客了,懒了,以后自觉写写博客,每周两三篇吧! 简单记录自己的学习经历,算是对自己的一点小小的督促! Java8的新特性很多,比如流处理在工作中看到很多的地方都在用,是时候扔掉 ...

  4. Java8新特性第3章(Stream API)

    Stream作为Java8的新特性之一,他与Java IO包中的InputStream和OutputStream完全不是一个概念.Java8中的Stream是对集合功能的一种增强,主要用于对集合对象进 ...

  5. Java8 新特性2——强大的Stream API

    强大的Stream API Stream 是 Java8 中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找.过滤和映射数据等操作.简而言之,Stream API 提供 ...

  6. java8新特性-lambda表达式和stream API的简单使用

    一.为什么使用lambda Lambda 是一个 匿名函数,我们可以把 Lambda表达式理解为是 一段可以传递的代码(将代码像数据一样进行传递).可以写出更简洁.更灵活的代码.作为一种更紧凑的代码风 ...

  7. Java8 新特性 Stream 非短路终端操作

    非短路终端操作 Java8 新特性 Stream 练习实例 非短路终端操作,就是所有的元素都遍厉完,直到最后才结束.用来收集成自己想要的数据. 方法有: 遍厉 forEach 归约 reduce 最大 ...

  8. Java8 新特性 Stream 短路终端操作

    短路终端操作 Java8 新特性 Stream 练习实例 传入一个谓词,返回传为boolean,如果符合条件,则直接结束流. 匹配所有 allMatch 任意匹配 anymMatch 不匹配 none ...

  9. Java8 新特性 Stream 无状态中间操作

    无状态中间操作 Java8 新特性 Stream 练习实例 中间无状态操作,可以在单个对单个的数据进行处理.比如:filter(过滤)一个元素的时候,也可以判断,比如map(映射)... 过滤 fil ...

随机推荐

  1. 高亮代码显示之HTML困惑

    近期做样式库,需要将HTML代码高亮,开始寻找相关的插件. 看到highlight.js,看到它主题样式如此之多,支持语言也如此之多,以为找到了神器.不想这只是痛苦的开始,为了让它支持HTML,我尝试 ...

  2. 设置java jvm(虚拟机) 的内存在大小

    package WanWan; public class Test { /** * @param args */ public static void main(String[] args) { // ...

  3. spark1.1.0下使用SparkSQL

    spark1.1.0的安装参见http://blog.csdn.net/bluejoe2000/article/details/41391407 安装了spark之后,可以在 shell中执行Spar ...

  4. 《JavaScript设计模式与开发实践》-面向对象的JavaScript

    设计模式 面向对象 动态类型语言 编程语言按照数据类型大体分为:静态类型语言和动态类型语言. 静态类型语言在编译时便已确定变量的类型,而动态类型语言的变量类型要到程序运行时,待变量被赋予某个值之后,才 ...

  5. iOS 应用测试最佳实践

    IOS改变了移动游戏,毫无疑问.它为“移动时代”铺平了道路,通过简单的用户体验提供惊人的功能.然而涉及到测试与监控,使用iPhone/iPad移动应用程序是除了简单之外的任何事情. 随着IOS应用市场 ...

  6. vue中使用LESS、SASS、stylus

    less的使用 npm install less less-loader --save 修改webpack.config.js文件.vue.cli 搭建项目可跳过此步 { test: /\.less$ ...

  7. 开启text汇聚排序

    开启text汇聚排序 curl -X PUT "http://192.168.1.136:19200/hxl_test/_mapping/tb_test" -H 'Content- ...

  8. 微信小程序笔记&lt;二&gt;认识app.json

    *.json文件在小程序开发中必不可少,从 app.json 开始认识小程序中的配置文件*.json: app.json 为小程序必须文件,它不仅作为配置文件管理着小程序的UI还充当着路由器的功能: ...

  9. html5+css3 权威指南阅读笔记(三)---表单及其它新增和改良元素

    一.新增元素及属性 1.表单内元素的form属性. html5: <form id="testForm"> <input type=text> </f ...

  10. C#中如何把byte[]数组转换成其他类型

    http://bbs.csdn.net/topics/20447859 byte[] bytes = new byte[256]; //receive some stream from network ...