【java基础】Stream流的各种操作
创始人
2025-06-01 01:26:36

文章目录

  • 基本介绍
  • 流的创建
  • 流的各种常见操作
    • forEach方法
    • filter方法
    • map方法
    • peek方法
    • flatMap方法
    • limit和skip方法
    • distinct方法
    • sorted方法
  • 收集结果
    • 收集为数组(toArray)
    • 收集为集合(collect)
    • 收集为Map
  • 关于流的一些说明(终结操作)
  • 总结

基本介绍

Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据。

Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。

Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。

与集合相比,流提供了一种可以让我们在更高概念级别上指定计算任务的数据视图

注意:学习Stream必须要十分清晰的了解lamdba表达式,如果lambda不清楚,请参考一篇文章彻底搞懂lambda表达式


流的创建

我们在学习流之前,应当先了解一下Stream这个类,Stream类的类图和方法如下

在这里插入图片描述
在这里插入图片描述

对于创建流,我们可以使用静态方法Stream.of来创建

在这里插入图片描述

该方法传入一个可变长度的参数,然后就会返回对应类型的流

        Stream stream = Stream.of(2, 3, 1, 4);

如果要创建一个不包含任何元素的流,可以使用Stream.empty

        Stream empty = Stream.empty();
 

我们还可以使用Stream的静态方法generate和iterate来创建无限流。

下面就通过generate创建了一个获取随机数的流

在这里插入图片描述

        Stream randomNumStream = Stream.generate(Math::random);

如果想要创建例如0,1,2,3这样有规律的序列流,那么就可以使用iterate方法

在这里插入图片描述

        Stream iterate = Stream.iterate(0, num -> num+1);

除了上面几个静态方法,对于流的创建还有许多方法,例如Arrays.stream方法

在这里插入图片描述

在Collection中有stream方法和parallelStream方法都可以返回一个Stream流,这也就说明了所有的集合都可以调用这2个方法返回对应的流

在这里插入图片描述

对于流,我们有几点注意事项如下

  • 流并不存储元素,这些元素可能存储在底层的集合中,或者是按需生成的
  • 流的操作不会改变其数据源
  • 流的操作尽可能惰性执行。这意味着直至需要其结果时,操作才会执行

流的各种常见操作

这里主要介绍在流里面使用频率较高的几个操作,每个方法都会给出该方法的源注释,以及基本使用,请参考注释和代码来进行理解


forEach方法

这个方法可以对流里面的每一个元素执行操作

在这里插入图片描述

        Stream stream = Stream.of(2, 3, 1, 4);stream.forEach(System.out::println);

输出结果如下

2
3
4
1

filter方法

该方法可以过滤掉流中不满足要求的元素,会返回一个新流

在这里插入图片描述

        Stream stream = Stream.of(2, 3, 1, 4);Stream newStream = stream.filter(num -> num > 2);System.out.print("过滤之后:");newStream.forEach(x -> System.out.print(x + " "));

上面代码输出如下

过滤之后:3 4 

map方法

当我们想要按照某种方式来转换流中的值的时候,我们就可以使用map

在这里插入图片描述

        Stream stream = Stream.of(2, 3, 1, 4);Stream newStream = stream.map(num -> num + 1);newStream.forEach(System.out::println);

上面代码输出如下

3
4
2
5

peek方法

该方法可以对流中的每一个元素进行操作,返回新的流

在这里插入图片描述

public class Dog {public String name;public Integer age;public Dog(String name, Integer age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Dog{" +"name='" + name + '\'' +", age=" + age +'}';}
}
        Dog[] dogs = {new Dog("tom", 1),new Dog("旺财", 2)};Stream dogStream = Arrays.stream(dogs);Stream newDogStream = dogStream.peek(dog -> dog.age = 999);newDogStream.forEach(System.out::println);

上面代码输出如下

Dog{name='tom', age=999}
Dog{name='旺财', age=999}

flatMap方法

该方法产生一个流,它是通过将传入lambda表达式应用于当前流中所有元素所产生的结果连接到一起而获得的。(注意,这里的每个结果都是一个流。)

在这里插入图片描述

        List> streamList = new ArrayList<>();Stream stream1 = Stream.of(1, 2, 3);Stream stream2 = Stream.of(4, 5, 6);Stream stream3 = Stream.of(7, 8, 9);streamList.add(stream1);streamList.add(stream2);streamList.add(stream3);Stream> stream = streamList.stream();// flatMap里面的lambda表达式应当返回一个流Stream integerStream = stream.flatMap(x -> x);integerStream.forEach(System.out::println);

上面代码输出如下

1
2
3
4
5
6
7
8
9

limit和skip方法

limit方法可以对流进行裁剪,只取前n个流,skip方法则是跳过前n个流

在这里插入图片描述
在这里插入图片描述

由于limit和skip用法基本由于,这里就用limit作为例子

        Stream stream = Stream.of(1, 2, 3, 4, 5, 6);Stream newStream = stream.limit(4);newStream.forEach(System.out::println);

上面代码输出如下

1
2
3
4

distinct方法

这个方法相当于去重

在这里插入图片描述

        Stream stream = Stream.of(1, 2, 3, 3, 1, 4);Stream newStream = stream.distinct();newStream.forEach(System.out::println);

代码输出如下

1
2
3
4

sorted方法

这个方法一看就知道是排序用的

在这里插入图片描述

该方法有2个,一个带有Comparator,就是用于指定排序方式的

        Stream stream = Stream.of(4, 1, 3, 2);Stream newStream = stream.sorted();newStream.forEach(System.out::println);

代码输出如下

1
2
3
4

收集结果

在上面我们都只是对流进行操作,现在来讲解下如何将流里面的数据收集到集合中。


收集为数组(toArray)

我们可以调用流里面的toArray方法,传入对应的类型数组即可
在这里插入图片描述

        Stream namesStream = Stream.of("tom", "luck", "jerry");String[] names = namesStream.toArray(String[]::new);System.out.println(Arrays.toString(names));

上面代码输出如下

[tom, luck, jerry]

收集为集合(collect)

调用stream里面的collect方法,然后传入指定的Collector实例即可,Collector提供了大量用于生成常见收集器的工厂方法。

Collector类的方法如下

在这里插入图片描述
在这里插入图片描述

可以发现有很多方法,这里先介绍几个常用的,其他的方法在后面文章中进行说明。

        List nums = Arrays.asList(1,2,3,1,4);

toList()可以将结果收集为List

        List list = nums.stream().collect(Collectors.toList());

toSet()可以将结果收集为Set

        Set set = nums.stream().collect(Collectors.toSet());

toCollection()可以指定收集的集的种类

        TreeSet treeSet = nums.stream().collect(Collectors.toCollection(TreeSet::new));

在Collector这个类里面还有其他的很多方法,建议大家去看看这个类的文档,对每个方法都有个影响,需要用到某种操作的时候查找文档即可。


收集为Map

Map也是集合,但是Map收集要比如List,Set等要麻烦一点,所以这里单独说明一下,toMap方法如下

在这里插入图片描述

我们需要指定k和v是什么,其实就是对于每一个元素,用什么来作为k和v

        Stream namesStream = Stream.of("tom", "jack", "lucy");Map namesMap = namesStream.collect(Collectors.toMap(k -> k.charAt(0), v -> v.toUpperCase()));System.out.println(namesMap);

上面代码就用字符串的第一个字符作为k,然后用字符串的大写作为v。上面代码输出如下

{t=TOM, j=JACK, l=LUCY}

使用toMap还有一点需要说明,就是key不能冲突,看下面代码,就会产生key冲突

        Stream namesStream = Stream.of("tom", "jack", "lucy","ttpfx");Map namesMap = namesStream.collect(Collectors.toMap(k -> k.charAt(0), v -> v.toUpperCase()));System.out.println(namesMap);

如果产生key冲突,那么collect方法会抛出一个一个IllegalStateException异常

在这里插入图片描述

对于key冲突的情况,我们应该给出解决key冲突的逻辑,toMap还有一个重载的方法,用于解决key冲突。也就是保留新值还是旧值

在这里插入图片描述

我们遇到key冲突旧保存最新的值即可

        Stream namesStream = Stream.of("tom", "jack", "lucy", "ttpfx");Map namesMap = namesStream.collect(Collectors.toMap(k -> k.charAt(0),v -> v.toUpperCase(),(oldV, newV) -> newV));System.out.println(namesMap);

上面代码输出如下

{t=TTPFX, j=JACK, l=LUCY}

对于toMap,都有一个等价的toConcurrentMap


关于流的一些说明(终结操作)

我们先来看下面代码

        Stream stream = Stream.of(2, 3, 1, 4);stream.forEach(System.out::println);Stream newStream = stream.filter(x -> x > 2);newStream.forEach(System.out::println);

上面代码逻辑很简单,就是先输出流里面的元素,然后过滤一下,最后再输出。按理说这个代码应该是没有问题的,我们运行一下

在这里插入图片描述

可以发现报错了,报错的原因就是说流已经关闭了,很奇怪啊,我们明明没有执行close操作

造成流关闭的原因就是 forEach方法。还记得在文章开始的说明吗?流是惰性执行的,在流执行终止操作前,流其实都没有执行。而forEach就是一个终止操作。对于终结方法,我们可以简单理解为就是返回值不是Stream的方法。

我们用代码验证一下Stream的惰性执行

        List list = new ArrayList<>();list.add(1);Stream stream = list.stream();list.add(2);long count = stream.count();System.out.println(count);

大家想一下,count是多少?由于Stream是惰性执行的,那么count显然应该就是2
在这里插入图片描述


总结

在这篇文章中介绍了Stream的一些基本使用,对于Stream还有许多的方法没有说明,这些会在后面的文章中进行说明。Stream里面还有一个很重要的Optional,这个将在下一篇文章中进行说明。

上一篇:幂等性通用组件

下一篇:day36_jdbc

相关内容

热门资讯

13寸电脑尺寸是多少厘米,13... 13寸电脑尺寸是多少厘米目录13寸电脑尺寸是多少厘米13英寸等于多少厘米13寸大概有多大?13.3寸...
管理员的英文缩写是什么,管理员... 管理员的英文缩写是什么目录管理员的英文缩写是什么管理员英文怎么写admn具体指的是什么?管理员的英文...
为什么喊张艺兴孙艺兴,张艺兴为... 为什么喊张艺兴孙艺兴目录为什么喊张艺兴孙艺兴张艺兴为什么叫孙兴?,孙艺兴和张艺兴是同一个人吗为什么喊...
肉沫土豆泥的做法,土豆泥怎么做... 肉沫土豆泥的做法目录肉沫土豆泥的做法土豆泥怎么做?土豆泥怎么做好吃,肉末土豆泥的家常做法土豆打成泥怎...
洛阳市区有哪些大学,洛阳有几所... 洛阳市区有哪些大学目录洛阳市区有哪些大学洛阳有几所大学求洛阳各大高校地址洛阳的大学有哪些洛阳市区有哪...
霎时间的近义词是什么,“ 霎时... 霎时间的近义词是什么目录霎时间的近义词是什么“ 霎时间 ”的近义词与“霎时间”意思相近的词有什么?霎...
如何画机器猫的简笔画,机器猫的... 如何画机器猫的简笔画目录如何画机器猫的简笔画机器猫的简笔画是怎样的?如何画哆啦a梦叮当的图案-如何画...
磁卡没有磁了小妙招,交通卡没有... 磁卡没有磁了小妙招目录磁卡没有磁了小妙招交通卡没有磁性怎么办磁卡消磁了怎样让其恢复?磁卡没有磁了怎么...
华为畅享6s是什么处理器,华为... 华为畅享6s是什么处理器目录华为畅享6s是什么处理器华为畅享6s:参数详解华为畅享6S外观及性能评测...
京东方普工干什么活,北京京东方... 京东方普工干什么活目录京东方普工干什么活北京京东方茶谷累不累合肥京东方一线员工做什么京东方普工,特工...
燕城是哪个城市,我的人间烟火燕... 燕城是哪个城市目录燕城是哪个城市我的人间烟火燕城是哪个城市?秦国燕城是现在的哪里燕城是哪个城市燕城是...
什么是黑洞谢谢告诉我,黑洞的基... 什么是黑洞谢谢告诉我目录什么是黑洞谢谢告诉我黑洞的基本性质?黑洞是什么?什么是黑洞什么是黑洞谢谢告诉...
光疗美甲怎么卸除,光疗甲怎么卸... 光疗美甲怎么卸除目录光疗美甲怎么卸除光疗甲怎么卸光疗甲要怎么卸下来?光疗甲怎么卸掉光疗美甲怎么卸除 ...
巧克力是怎么做成的,巧克力是用... 巧克力是怎么做成的目录巧克力是怎么做成的巧克力是用什么做成的 巧克力是用啥做的巧克力是什么做的巧克力...
感慨生活不易但励志的句子,关于... 感慨生活不易但励志的句子目录生活很苦的励志说说 励志开心的说说关于在艰难的路上的励志句子生活不易下一...
等腰三角形三线合一怎么证明,如... 等腰三角形三线合一怎么证明目录等腰三角形三线合一怎么证明如果只告诉三角形是等腰三角形,那么直接能证明...
番禺有哪些公园好玩的,广州市番... 番禺有哪些公园好玩的目录番禺有哪些公园好玩的广州市番禺区有哪些公园广州番禺有哪些公园好玩番禺旅游必去...
研究生读几年研究生的介绍,研究... 研究生读几年研究生的介绍目录研究生读几年研究生的介绍研究生读几年学制研究生是啥啊?国内研究生读几年研...
擦什么可以让纹身变淡,抹点什么... 擦什么可以让纹身变淡目录擦什么可以让纹身变淡抹点什么可以淡化纹身什么可以淡纹身不花钱去掉纹身的小窍门...
61键电子琴各个琴键代表什么,... 61键电子琴各个琴键代表什么目录61键电子琴各个琴键代表什么如何认识61键电子琴电子琴上的按钮分别是...
汽车钣金是什么意思(汽车钣金是... 今天给各位分享汽车钣金是什么意思的知识,其中也会对汽车钣金是什么意思的照片进行解释,如果能碰巧解决你...
40尺的高柜集装箱尺寸是多少(... 本篇文章极速百科给大家谈谈40尺的高柜集装箱尺寸是多少,以及40尺的高柜集装箱尺寸是多少寸对应的知识...
斗罗大陆唐三的魂环分别是什么,... 斗罗大陆唐三的魂环分别是什么目录斗罗大陆唐三的魂环分别是什么唐家三少的《斗罗大陆》一书中,主角唐三的...
浅色硅胶手机壳脏了怎么清洗,硅... 1. 准备工具:洗洁精、牙膏、牙刷、风油精、棉签、橡皮擦和抹布。 以上内容仅供参考,可阅读硅胶...
英雄联盟lng是哪个战队,ln... 英雄联盟lng是哪个战队目录英雄联盟lng是哪个战队lng是哪个国家的战队lng打野tarzan哪国...
有没有学习美妆的软件,有什么教... 有没有学习美妆的软件目录有没有学习美妆的软件有什么教化妆的app?有什么美妆的APP有什么教化妆的a...
黑芝麻一天吃多少合适,每天吃多... 黑芝麻一天吃多少合适目录黑芝麻一天吃多少合适每天吃多少黑芝麻为宜黑芝麻每天吃多少合适?黑芝麻每天吃多...
东风标志307三厢车多长(东风... 今天给各位分享东风标志307三厢车多长的知识,其中也会对东风标志307三厢车多长多宽进行解释,如果能...
法国百科法国女人最钟爱的香水是... 本篇文章极速百科给大家谈谈法国百科法国女人最钟爱的香水是?,以及法国的什么香水最有名对应的知识点,希...
自然灾难电影有哪些 极速百科网... 自然灾难电影有哪些目录自然灾难电影有哪些自然灾难电影有哪些自然灾难片都有那些?像(后天)(烈火雄心)...