Java8新特性:stream流应用,丢掉for循环实现复杂遍历功能
admin
2024-03-14 03:22:03
0

stream流

stream流是支持数据处理操作的数据源生成的元素序列,这些数据源可以是集合、数组、文件I/O channel等。stream不是一种数据结构,也不会存储数据,并且它支持数据聚合操作,如过滤filter、映射map、去重distinct、匹配match等等。

stream流操作可以分为,生成stream流、操作stream流(中间操作和终端操作)。

生成stream

有两种方式创建stream

  1. stream() − 为集合创建串行流。
  2. parallelStream() − 为集合创建并行流。

通过集合生成

集合实例后面直接.stream()就可以非常方便的创建一个stream。比如List、Set、Map集合都可以通过这种方式创建stream。

List list = Arrays.asList("欢迎阅读", "鳄鱼儿"); 
list.stream();
list.parallelStream()

通过数组生成

使用Arrays.stream()方法生成流,生成流的类型是数值流IntStream。除了IntStreamLongStream DoubleStream

int[] arr = new int[]{1,2,3};
IntStream stream = Arrays.stream(arr);

通过文件生成

通过Files.lines(path, Charset)生成stream。

注意:此时生成的流需要需要手动关闭,通过一个BaseStream.close()方法和实现AutoCloseable。一般来说几乎所有的流实例实际上不需要在使用后关闭,只有来源为I/O channel的流才需要如此。

Stream lines = Files.lines(Paths.get("./test.txt"), Charset.defaultCharset());

流的操作

stream操作类型分为两种,中间操作和终端操作。

中间操作

中间操作即代表一个stream后返回的还是stream,其后面仍可以跟随中间操作,比如过滤filter后仍可以接distinct去重。

filterdistinctsortedlimitskip

通过以下代码展示filterdistinctsortedlimitskip的用法。

  1. 通过filter过滤掉小于2的元素
  2. 通过distinct去掉重复的元素
  3. 通过sorted对元素从小到大排序
  4. 通过skip忽略掉前2个元素
  5. 再通过limit截取前5个元素
  6. 最后通过forEach进行遍历输出。
  7. 输出结果为:4
    6
    8
    12
    55
public static void main(String[] args) {List list = Arrays.asList(1, 12, 6, 8, 4, 55, 6, 77, 66, 12);list.stream().filter(item -> item > 2)   // 过滤元素 1.distinct()                 // 去重 12.sorted()                   // 排序.skip(2)                    // 跳过流中元素 4 6.limit(5)                   // 保留前5个元素.forEach(System.out::println);  // 输出
}

mapmapToIntmapToLongmapToDoubleflatMap

map流映射,即将元素映射成另外一个新的元素,这是一种一对一关系。
flatMap流转换,即将一个流中的每个值都转换为另一个流,是一种一对多的关系.

比如参考以下代码

List stringList = Arrays.asList("欢迎 阅读", "鳄鱼儿 文章");
List strLen = stringList.stream().map(item -> item.length()).collect(Collectors.toList());
System.out.println(strLen);List newStrList = stringList.stream().flatMap(item -> Arrays.stream(item.split(" "))).collect(Collectors.toList());
System.out.println(newStrList);;

输出结果分别是

  1. [5, 6],String 转变成了 Integer
  2. [欢迎, 阅读, 鳄鱼儿, 文章],一个流中的每个值都转换为另一个流,最好组合成一个新的stream。

mapToIntmapToLongmapToDouble分别是返回一个IntStreamLongStreamDoubleStream
这些类型的stream包括一些sum()max()
min()方法等,可以用于计算,如下面代码求和示例:

List list = Arrays.asList(1, 12, 6, 8, 4, 55, 6, 77, 66, 12);
// 转换IntStream
list.stream().mapToInt(item -> item * 2).forEach(System.out::println); 
// 对IntStream内元素进行计算,并求和 
System.out.println(list.stream().mapToInt(item -> item * 2).sum());

peekforeach

peekforeach是对元素进行遍历处理的方法。

区别在于peek是中间操作,foreach是终端操作,

List list = Arrays.asList(1, 12, 6, 8, 4, 55, 6, 77, 66, 12);
// 如果没有终端操作,则peek不会执行
list.stream().peek(System.out::println);// 有终端操作,先执行peek,再返回count,最后通过println输出
System.out.println(list.stream().peek(System.out::println).count()
);
// foreach是终端操作
list.stream().forEach(System.out::println);

输出结果:

  1. 1 12 66 12
  2. 4
  3. 1 12 66 12

终端操作

终端操作即一个stream的终止(关闭),一个stream中只能有一个终端操作。

allMatchanyMatchnoneMatch

  1. allMatch:匹配所有元素
  2. anyMatch:匹配其中一个元素
  3. noneMatch:全部元素都不匹配,跟allMatch相反
List integerList = Arrays.asList(1, 3);if (integerList.stream().allMatch(i -> i > 5)) {System.out.println("所有元素值都大于5");
} else {System.out.println("并非所有元素值都大于5");
}if (integerList.stream().anyMatch(i -> i > 5)) {System.out.println("存在值大于5的元素");
} else {System.out.println("不存在值大于5的元素");
}if (integerList.stream().noneMatch(i -> i > 5)) {System.out.println("元素值都小于5");
} else {System.out.println("元素值不都小于5");
}

输出结果:

  1. 并非所有元素值都大于5
  2. 不存在值大于5的元素
  3. 元素值都小于5

countmaxmin

  1. count: 统计流中元素个数
  2. max: 获取流中最大值
  3. min: 获取流中最小值
List stringList = Arrays.asList("欢迎 阅读", "鳄鱼儿 文章");Optional min = stringList.stream().map(String::length).min(Integer::compareTo);stringList.stream().mapToInt(String::length).min();

有两种写法,通过传参min(Comparatorcomparator)。或者转换成为IntStream再进行min操作。

findAnyfindFirst

  1. findAny:从符合条件的元素中,随机查找到一个元素
  2. findFirst:根据条件查找到符合条件的第一个元素
List list = Arrays.asList(1, 12, 66, 12);System.out.println(list.stream().filter(i -> i > 3).findFirst().orElse(-1));
System.out.println(list.stream().filter(i -> i > 3).findAny().orElse(-1));

结果输出:

  1. 12
  2. 12

总结

到此,基础Stream用户就已经说完了,看到这里我们会发现,所以的stream其实都可以用for循环来实现,而我们全篇都没有使用for循环来实现,这些如果用for循环实现,你会发现实现的语句变得复杂了很多,不信的话,你可以试试。

我们也可以看到stream带来的好处,包括代码更简洁解耦等。

相关内容

热门资讯

钱、资源、工厂,深圳“草根”创... 在深圳,一个没有大厂背景的普通创业者,仅靠一个想法,就能快速完成融资、产品测试、量产、产品上市等多个...
中国证监会发布《私募投资基金信... 新华社北京2月27日电(记者刘慧、刘羽佳)中国证监会2月27日发布了《私募投资基金信息披露监督管理办...
原创 津... 今天来给大家聊一下津巴布韦对锂精矿和原矿的新动作。凌晨的美股市场,锂矿龙头Sigma Lithium...
SpaceX传最快3月秘密递交... 来源:21世纪经济报道 21世纪经济报道记者 彭新 2月28日消息,据媒体援引知情人士称,马斯克旗下...
淘宝闪购发布并开源食安治理AI... 上证报中国证券网讯(记者 杨翔菲)餐饮行业食安治理领域再添一枚重磅AI利器。近日,淘宝闪购正式发布专...
原创 济... 鲁网2月28日讯为持续优化营商环境,精准掌握辖区企业复工复产情况与发展需求,2月28日,济南市莱芜区...
原创 9... 桃李满天下,是面包的梦想。 作者 | 方璐 于婞 编辑丨于婞 来源 | 野马财经 近日,桃李面包(6...
港股IPO结构大变迁,粤企募资... 来源:21世纪经济报道 南方财经记者 王达毓 广州报道 2025年港股火力全开,港交所业绩再创新高。...
减肥人群,迎来好消息! 随着减重药巨头诺和诺德重磅GLP-1类药物司美格鲁肽在中国的核心分子专利即将于3月到期,一大批中国本...
原创 特... 今天来给大家分析一下,为何美国加税,却将中国排除在外。当地时间2月24日,特朗普在国会发表了长达10...
原创 5... 江苏话爆笑科普:5角硬币里真有黄金?别再傻乎乎囤啦! 最近啊,不管是小区楼下张阿姨、李伯伯拉家常,...
电动平车出口优选山东金通,多类... 在全球工业物流设备领域,电动平车作为短途运输的核心工具,其性能与稳定性直接影响生产效率。山东金通起重...
张精科获批出任杭州银行行长 北京商报讯(记者 孟凡霞 周义力)2月28日,国家金融监督管理总局浙江监管局发布《关于张精科杭州银行...
远期售汇业务外汇风险准备金率下... 本报讯(记者 潘福达)昨天,中国人民银行发布消息称,为促进外汇市场发展,支持企业管理好汇率风险,中国...
节后“舌尖经济”热度不减 春菜... 央视网消息:随着气温逐渐升高,多地的春菜陆续上市,在江苏、上海、广西等地的市场上,具有本地特色的春菜...
老铺黄金开年首轮涨价超20%,... 老铺黄金今日涨价,记者根据目前在售的产品进行不完全统计,老铺2026年开年首轮调价幅度约为20%-3...
为何还有人能靠茅台赚钱?因为他... 这个世界出BUG了 李凯,小程序“易茅时价”的创始人,最近一年,他的营收上涨了40%,根据经验,他...
年内首现两家期货公司被罚停开新... 来源:格隆汇APP 格隆汇2月28日|在监管力度加大的背景下,暂停新开业务的处罚在期货行业近期披露的...
伊朗局势演变会如何影响美股、黄... 来源:财联社 最近几周,美伊紧张局势的加剧,再次促使交易员根据风险情绪和波动性来勾勒潜在的地区事态...
童鞋店必看!低成本获客不烧钱,... 做童鞋店的宝子们,是不是都有同一个痛点?想靠小红书获客,却要么砸钱投流没效果,要么自己瞎发笔记没人看...