百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

Java(JDK 8+)新特性之流(Streams)核心 API 简介

bigegpt 2024-08-27 11:54 2 浏览

说明:

本文为牛旦教育原创,头条首发,非头条转发请注明来源和原文网址。

1.摘要

在本文中,我们将快速浏览Java 8+添加的一个主要功能——流(Streams)。

我们将通过简单的示例来解释流是什么、创建流和基本流操作等。

2. 流 API

Java 8+中的一个主要新特性是引入了流功能,在包java.util.stream中,其中包含了几个用于处理元素序列的类。

流核心API类是Stream<T>。接下来内容将演示如何使用现有的数据提供源创建流。

2.1.流创建

可以从不同的元素源来创建流,例如 借助集合或数组的stream()和of()方法的帮助

String[] arr = new String[]{"a", "b", "c"};
Stream<String> stream = Arrays.stream(arr);
stream = Stream.of("a", "b", "c");

缺省的stream()方法已添加到Collection接口,且方法已做了默认实现,允许使用任何集合来作为元素源创建Stream<T>:

Stream<String> stream = list.stream();

2.2.多线程流

Stream API还通过提供parallelStream()方法简化了多线程,该方法在并行模式下对流的元素运行操作。

下面的代码允许为流的每个元素并行运行方法doWork()

list.parallelStream().forEach(element -> doWork(element));

下面将介绍一些基本的流API操作。

3.流操作

在流上可以执行许多有用的操作。

它们分为中间操作(返回Stream<T>)和终端操作(返回确定类型的结果)。中间操作允许链接。

另外,值得注意的是,对流的操作不会更改源数据。

下面是一个示例

long count = list.stream().distinct().count();

上面这个distinct() 方法表示一个中间操作,它创建前面流的唯一元素的新流。count() 方法是一个终端操作,它返回流的大小。

3.1. 迭代

Stream API 有助于替换for、for-each及 while 循环。它允许专注于操作的逻辑,但不能专注于元素序列上的迭代。例如:

for (String str : list) {
 if (str.contains("a")) {
 return true;
 }
}

只需使用一行 Java 8+ 代码即可更改上述的代码块:

boolean isExist = list.stream().anyMatch(element -> element.contains("a"));

3.2. 过滤

filter() 方法允许我们选取满足谓词的元素流。

我们来考虑以下列表:

ArrayList<String> list = new ArrayList<>();
list.add("One");
list.add("OneAndOnly");
list.add("Derek");
list.add("Change");
list.add("factory");
list.add("justBefore");
list.add("Italy");
list.add("Italy");
list.add("Thursday");
list.add("");
list.add("");

以下代码创建了列表List<String>的Stream<String>,查找此流中包含字符"d"的所有元素,并创建一个仅包含过滤元素的新流:

Stream<String> stream = list.stream().filter(element -> element.contains("d"));

3.3. 映射

要通过向流应用特殊函数来转换流元素,并将这些新元素收集到流中,我们可以使用 map()方法,如下所示:

List<String> uris = new ArrayList<>();
uris.add("C:\\My.txt");
Stream<Path> stream = uris.stream().map(uri -> Paths.get(uri));

上述代码通过将特定的 lambda 表达式应用于初始流的每个元素,将 Stream<String> 转换为Stream<Path>。

如果流中每个元素都包含其自己的元素序列,并且想要创建这些内部元素的流,则应使用 flatMap() 方法,如下所示:

List<Detail> details = new ArrayList<>();
details.add(new Detail());
Stream<String> stream
 = details.stream().flatMap(detail -> detail.getParts().stream());

在此示例中,我们有一个Detail类型的元素列表。Detail类包含一个字段 PARTS,该字段是List<String>。在 flatMap() 方法的帮助下,将提取字段 PARTS 中的每个元素,并将其添加到新的结果流中。之后,初始的Stream<Detail>将被丢失。

3.4. 匹配

Stream API 提供了一组方便的工具,用于根据某些谓词验证序列的元素。为此可以使用以下方法之一:anyMatch(), allMatch(), noneMatch()。这些名字是不言自明的。下面是些返回布尔的终端操作。

boolean isValid = list.stream().anyMatch(element -> element.contains("h")); // true
boolean isValidOne = list.stream().allMatch(element -> element.contains("h")); // false
boolean isValidTwo = list.stream().noneMatch(element -> element.contains("h")); // false

3.5. 缩减(Reduction)

Stream API 允许借助 Stream 类型的 reduce() 方法,根据指定的函数将元素序列缩减到某个值。此方法采用两个参数:第一个,起始值。第二个,累加器函数。

注意:缩减(Reduction),是一种广泛使用的计算模型,特别是在并行计算领域。简单地来说,Reduction就是一系列的划分(Partition)和汇总(Summarize)操作的集合:对输入数据分块,对每一个分块汇总,然后再将汇总后的数据视为新的输入数据,重复分块和汇总,直到得到最终结果,可以想象为一个倒置的树。Google和Hadoop的Map/Reduce中的Reduce计算就是一个很好的例子。

假设您有一个 List<Integer>,并且想要拥有所有这些元素与某初始化整数的总和(在此示例中为 23)。那么,可以运行以下代码,结果将为 26 (23 + 1 + 1 + 1)。

List<Integer> integers = Arrays.asList(1, 1, 1);
Integer reduced = integers.stream().reduce(23, (a, b) -> a + b);

3.6. 收集

缩减(Reduction)也可以由流的 collect() 方法提供。在将流转换为集合或映射,并且以单个字符串的形式表示流时,此操作非常方便。有一个实用程序类Collectors,它为几乎所有典型的收集操作提供解决方案。对于某些非常规任务,可以创建自定义收集器。

List<String> resultList 
 = list.stream().map(element -> element.toUpperCase()).collect(Collectors.toList());

此代码使用最终端 collect() 操作将Stream<String>缩减到List<String>。

4. 总结

在本文中,我们简要地讨论了Java流--绝对是Java 8+最有趣的功能之一。

使用流还有更高级的示例,此文的目的只是提供快速和实用的介绍,引导你可以使用这些功能做点什么,并作为探索和进一步学习的起点。

后序在写写深入 Stream API 的文章和实战案例。

好叻,就写这么多了,分享出去吧 。

相关推荐

10w qps缓存数据库——Redis(redis缓存调优)

一、Redis数据库介绍:Redis:非关系型缓存数据库nosql:非关系型数据库没有表,没有表与表之间的关系,更不存在外键存储数据的形式为key:values的形式c语言写的服务(监听端口),用来存...

Redis系列专题4--Redis配置参数详解

本文基于windowsX64,3.2.100版本讲解,不同版本默认配置参数不同在Redis中,Redis的根目录中有一个配置文件(redis.conf,windows下为redis.windows....

开源一夏 | 23 张图,4500 字从入门到精通解释 Redis

redis是目前出场率最高的NoSQL数据库,同时也是一个开源的数据结构存储系统,在缓存、数据库、消息处理等场景使用的非常多,本文瑞哥就带着大家用一篇文章入门这个强大的开源数据库——Redis。...

redis的简单与集群搭建(redis建立集群)

Redis是什么?是开源免费用c语言编写的单线程高性能的(key-value形式)内存数据库,基于内存运行并支持持久化的nosql数据库作用主要用来做缓存,单不仅仅是做缓存,比如:redis的计数器生...

推荐几个好用Redis图形化客户端工具

RedisPlushttps://gitee.com/MaxBill/RedisPlusRedisPlus是为Redis可视化管理开发的一款开源免费的桌面客户端软件,支持Windows、Linux...

关于Redis在windows上运行及fork函数问题

Redis在将数据库进行持久化操作时,需要fork一个进程,但是windows并不支持fork,导致在持久化操作期间,Redis必须阻塞所有的客户端直至持久化操作完成。微软的一些工程师花费时间在解决在...

你必须懂的Redis十大应用场景(redis常见应用场景)

Redis作为一款高性能的键值存储数据库,在互联网业务中有着广泛的应用。今天,我们就来详细盘点一下Redis的十大常用业务场景,并附上Golang的示例代码和简图,帮助大家更好地理解和应用Redis。...

极简Redis配置(redis的配置)

一、概述Redis的配置文件位于Redis安装目录下,文件名为redis.conf(Windows名为redis.windows.conf,linux下的是redis.conf)你可以通过C...

什么是redis,怎么启动及如何压测

从今天起咱们一起来学习一下关于“redis监控与调优”的内容。一、Redis介绍Redis是一种高级key-value数据库。它跟memcached类似,不过数据可以持久化,而且支持的数据类型很丰富。...

一款全新Redis UI可视化管理工具,支持WebUI和桌面——P3X Redis UI

介绍P3XRedisUI这是一个非常实用的RedisGUI,提供响应式WebUI访问或作为桌面应用程序使用,桌面端是跨平台的,而且完美支持中文界面。Githubhttps://github....

windows系统的服务器快速部署java项目环境地址

1、mysql:https://dev.mysql.com/downloads/mysql/(msi安装包)2、redis:https://github.com/tporadowski/redis/r...

window11 下 redis 下载与安装(windows安装redis客户端)

#热爱编程是一种怎样的体验#window11下redis下载与安装1)各个版本redis下载(windows)https://github.com/MicrosoftArchive/r...

一款轻量级的Redis客户端工具,贼好用!

使用命令行来操作Redis是一件非常麻烦的事情,我们一般会选用客户端工具来操作Redis。今天给大家分享一款好用的Redis客户端工具TinyRDM,它的界面清新又优雅,希望对大家有所帮助!简介Ti...

一个.NET开发且功能强大的Windows远程控制系统

我们致力于探索、分享和推荐最新的实用技术栈、开源项目、框架和实用工具。每天都有新鲜的开源资讯等待你的发现!项目介绍SiMayRemoteMonitorOS是一个基于Windows的远程控制系统,完...

Redis客户端工具详解(4款主流工具)

大家好,我是mikechen。Redis是大型架构的基石,也是大厂最爱考察内容,今天就给大家重点详解4款Redis工具@mikechen本篇已收于mikechen原创超30万字《阿里架构师进阶专题合集...