Java8 Stream详解及创建流方法使用示例(二)

news2025/1/24 18:02:41

        本章介绍Stream 创建流的操作:创建流指的是将一个集合或其他数据源转换为 Stream 流对象的过程。通常情况下,我们可以使用 Stream 类的静态方法来创建流对象,如 Stream.of()、Collections.stream() 等。这些方法将返回一个 Stream 流对象,该对象可用于对数据进行各种操作。下面是一些常用的创建流的方法。Java8 Stream详解及中间操作创建方法使用示例(一)

  1. of(T... values):创建一个由指定元素组成的流。
  2. empty():创建一个空的流。
  3. generate(Supplier<T> s):创建一个无限流,每次调用 get() 方法都会生成新的数据。
  4. iterate(T seed, UnaryOperator<T> f):创建一个无限流,在每次迭代时都会应用指定的函数。
  5. concat(Stream<? extends T> a, Stream<? extends T> b):创建一个包含两个流的顺序流,先是流 a,再是流 b。
  6. builder():创建一个用于构建链式操作的 Builder 对象。
  7. ofNullable(T t):创建一个包含零个或一个元素的流,元素为指定对象(可以为 null)。
  8. range(int startInclusive, int endExclusive):创建一个包含从 startInclusive 开始(含)到 endExclusive 结束(不含)的整数序列流。
  9. rangeClosed(int startInclusive, int endInclusive):创建一个包含从 startInclusive 开始(含)到 endInclusive 结束(含)的整数序列流。

Stream创建流的方法详细介绍

of(T... values)

Stream的of(T... values)方法是一个静态方法,用于创建一个包含指定元素的顺序Stream对象。

具体用法如下:

  1. 调用of(T... values)方法并传入一个或多个元素。
  2. 该方法将返回包含指定元素的Stream对象。

例如,以下代码演示了如何使用of()方法创建一个包含多个元素的Stream对象:

Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);

上述代码将创建一个包含整数1到5的Stream对象。可以根据需要使用该流进行后续操作,例如过滤、映射、排序等操作。

of(T t)

Stream的of(T t)方法是一个静态方法,用于创建一个包含单个元素的顺序Stream对象。

具体用法如下:

  1. 调用of(T t)方法并传入一个元素。
  2. 该方法将返回包含指定元素的Stream对象。

例如,以下代码演示了如何使用of()方法创建一个包含单个元素的Stream对象:

Stream<String> stream = Stream.of("Hello");

上述代码将创建一个包含字符串"Hello"的Stream对象。可以根据需要使用该流进行后续操作,例如过滤、映射、排序等操作。

 empty()

empty() 方法是用来创建一个不包含任何元素的空流。

下面是一个使用示例:

import java.util.stream.Stream;

public class StreamEmptyExample {
    public static void main(String[] args) {
        Stream<String> emptyStream = Stream.empty();
        System.out.println("Count: " + emptyStream.count()); // 输出 Count: 0
    }
}

以上代码展示了如何使用 empty() 方法创建一个空流。直接调用 Stream.empty() 方法即可得到一个不包含任何元素的空流。接着,使用 count() 方法获取流中元素的数量,由于该流为空,所以返回值为 0。最终将其打印出来。

需要注意的是,由于该流不包含任何元素,因此对它进行任何操作都不会有任何影响,也不会引发任何异常。

generate(Supplier<T> s)

generate() 方法是 Stream 类中的一个静态方法,它接收一个 Supplier 函数作为参数,用于生成元素序列。generate() 方法会按照生成函数的逻辑无限地生成元素,直到达到流的上限或被用户中断。

例如,假设需要生成一个由随机整数构成的流,可以使用 generate() 方法实现:

Random random = new Random();
Stream<Integer> intStream = Stream.generate(() -> random.nextInt(100));

以上代码中,首先创建了一个 Random 对象用于生成随机整数,然后通过 Stream.generate() 方法创建了一个新的流,并传入一个生成函数 () -> random.nextInt(100),用于生成随机整数。由于 generate() 方法不会限制元素数量,因此这个流会一直生成随机整数,直到被强制停止。

需要注意的是,由于 generate() 方法生成的流是无限的,因此如果不对流进行限制,可能会导致程序陷入死循环或内存溢出等问题。如果需要将流转换为有限长度的流,可以使用 limit() 方法或 takeWhile() 方法。

另外,由于 generate() 方法是一个静态方法,因此可以在任何地方调用它创建新的流。同时,由于生成函数是无状态的,因此可以并行生成元素以提高效率。

iterate(T seed, UnaryOperator<T> f)

iterate() 方法是 Stream 类中的一个静态方法,它接收一个起始元素和一个一元操作函数作为参数,用于生成一个包含无限连续元素的流。iterate() 方法会将起始元素作为序列的第一个元素,并以这个元素为基础,通过一元操作函数不断生成新的元素。

例如,假设需要生成一个包含斐波那契数列的流,可以使用 iterate() 方法实现:

Stream.iterate(new int[]{0, 1}, arr -> new int[]{arr[1], arr[0] + arr[1]})
      .mapToInt(arr -> arr[0])
      .limit(10)
      .forEach(System.out::println);

以上代码中,首先通过 Stream.iterate() 方法定义了一个起始元素 {0, 1} 和一元操作函数 arr -> new int[]{arr[1], arr[0] + arr[1]},用于生成下一个斐波那契数列元素。然后通过 mapToInt() 方法将每个元素转换为斐波那契数列中的第一个数,并通过 limit() 方法限制了元素数量为 10。最后通过 forEach() 方法将每个元素输出到控制台。

需要注意的是,由于 iterate() 方法生成的流是无限的,因此如果不对流进行限制,可能会导致程序陷入死循环或内存溢出等问题。如果需要将流转换为有限长度的流,可以使用 limit() 方法或 takeWhile() 方法。

另外,由于一元操作函数是无状态的,因此可以并行生成元素以提高效率。同时,由于 iterate() 方法生成的流是有序的,因此不建议在并行流中使用。

 concat(Stream<? extends T> a, Stream<? extends T> b)

Stream 接口中的静态方法 concat(Stream<? extends T> a, Stream<? extends T> b) 可以将两个流连接起来,形成一个新的流。这个新的流包含了两个原始流的所有元素,先按照第一个流的顺序排列,然后再按照第二个流的顺序排列。

下面是一个使用示例:

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class StreamConcatExample {
    public static void main(String[] args) {
        List<String> list1 = Arrays.asList("A", "B", "C");
        List<String> list2 = Arrays.asList("D", "E", "F");

        Stream<String> stream1 = list1.stream();
        Stream<String> stream2 = list2.stream();

        Stream<String> concatStream = Stream.concat(stream1, stream2);

        List<String> result = concatStream.collect(Collectors.toList());

        System.out.println(result); // [A, B, C, D, E, F]
    }
}

以上代码展示了如何使用 concat() 方法连接两个字符串列表的示例。首先创建了两个列表 list1list2,然后通过 stream() 方法将它们转换为流,得到两个流 stream1stream2。接着,通过 concat(stream1, stream2) 方法将这两个流连接起来,得到一个新的流 concatStream,该流包含了两个原始流中的所有元素。最后,通过 collect(Collectors.toList()) 方法将该新流中的元素收集到一个列表中,得到一个包含所有元素的列表 result

需要注意的是,在使用 concat() 方法时,需要保证两个流中的元素类型相同。另外,一旦某个流被操作过,比如使用了 filtermap 等方法,那么就不能再对该流进行连接操作,否则会抛出 IllegalStateException 异常。

 builder()

用于创建可变的、支持添加元素的 Stream

以下是 builder() 方法的使用示例:

Stream<String> stream = Stream.<String>builder()
        .add("apple")
        .add("banana")
        .add("orange")
        .build();

stream.forEach(System.out::println);

上述代码中,首先使用 Stream.builder() 创建了一个 Stream.Builder 对象,然后使用 add() 方法向该对象中添加了三个字符串元素。最后通过调用 build() 方法创建了一个新的 Stream 对象,并使用 forEach() 方法输出其中的元素。

需要注意的是,由于 Stream.Builder 是可变的,所以应当仅在必要的情况下使用 builder() 方法来创建 Stream 对象。在其他情况下,应当使用不可变的集合或数组来创建 Stream 对象,以避免出现并发问题。

 ofNullable(T t)

Java 8 中的 Stream 类提供了 ofNullable(T t) 方法,用于创建包含零个或一个元素的流对象。该方法接受一个类型为 T 的参数 t,可以是任何对象,包括 null。如果参数 t 不为 null,那么将创建一个包含该元素的、长度为1的流;否则,将创建一个空流,即不包含任何元素。

该方法返回的是一个 Optional 对象,可以通过调用其 stream() 方法来获取对应的 Stream 流对象。如果参数 t 不为 null,则该流对象中仅包含一个元素 t;否则,该流对象为空。

举例来说,我们可以使用 ofNullable(T t) 方法来判断一个对象是否为 null,并将其转换为一个流对象。例如:

String str = null;
Stream<String> stream = Stream.ofNullable(str);
 
 

上述代码将创建一个空流对象 stream,因为 str 为 null。如果 str 非空,则会创建包含 str 元素的流对象。

ofNullable(T t) 方法通常用于处理类似数据源为空时的情况,例如在流式计算中,当数据源为空时需要特殊处理,此时可以使用 ofNullable() 方法来方便地将其转换为空流对象。同时,该方法还可以用于简化一些流式计算的操作,例如使用 filter() 方法过滤空值时,可以借助 ofNullable() 方法将空值转换为空流对象后再进行过滤。

总之,ofNullable(T t) 方法可以方便地将一个对象转换为包含零个或一个元素的流对象,通常用于处理空值情况和简化编码操作。

range(int startInclusive, int endExclusive)

range(int startInclusive, int endExclusive) 是 Java 8 中 Stream 类提供的一个静态方法,用于创建一个包含从 startInclusive 开始(含)到 endExclusive 结束(不含)的整数序列流对象。该方法返回的是一个 IntStream 流对象,可以对该流进行各种操作。

下面是一个示例,演示如何使用 range() 方法创建一个整数序列流:

IntStream intStream = IntStream.range(1, 10);
intStream.forEach(System.out::print); // 输出:123456789

上述代码中,我们使用 range() 方法创建了一个从1到10的整数序列流对象,并将其存储在 intStream 变量中。然后,我们调用 intStream 对象的 forEach() 方法,使用方法引用 System.out::print 来依次输出每个元素,从而得到了1到9的输出结果。

需要注意的是,使用 range() 方法创建的整数序列流对象不包含结束值 endExclusive,即该区间是左闭右开的。因此,在上述示例中,输出的结果是从1到9,不包括数字 10。

rangeClosed(int startInclusive, int endInclusive) 

rangeClosed(int startInclusive, int endInclusive) 是 Java 8 中 Stream 类提供的一个静态方法,用于创建一个包含从 startInclusive 开始(含)到 endInclusive 结束(含)的整数序列流对象。该方法返回的是一个 IntStream 流对象,可以对该流进行各种操作。

下面是一个示例,演示如何使用 rangeClosed() 方法创建一个整数序列流:

IntStream intStream = IntStream.rangeClosed(1, 10);
intStream.forEach(System.out::print); // 输出:12345678910

上述代码中,我们使用 rangeClosed() 方法创建了一个从1到10的整数序列流对象,并将其存储在 intStream 变量中。然后,我们调用 intStream 对象的 forEach() 方法,使用方法引用 System.out::print 来依次输出每个元素,从而得到了1到10的输出结果。

需要注意的是,使用 rangeClosed() 方法创建的整数序列流对象包含结束值 endInclusive,即该区间是左闭右闭的。因此,在上述示例中,输出的结果是从1到10,包括数字 10。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/632231.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【模块三:职业成长】35|模块导读:回过头来看,你觉得架构师到底是做什么的?

你好&#xff0c;我是郭东白。我们今天就正式进入模块三的学习了。 我们在开篇词里面介绍了&#xff0c;模块三的目的是向你介绍架构师的能力维度&#xff0c;以及获取这些能力的方法。既然是总结架构师成长的课程&#xff0c;那么“什么是架构师”就是一个绕不过去的话题。 …

操作系统-内存管理-虚拟内存管理

目录 一、虚拟内存定义和特征 二、请求分页管理 页表机制 缺页中断机构 地址变换机构 三、页面置换算法 3.1最佳置换算法(OPT) 3.2先进先出置换算法(FIFO) 3.3最近最久未使用置换算法(LRU) 3.4时钟置换算法(CLOCK) 3.4.1简单时钟置换算法 3.4.2改进型时钟置换算法 四、…

数据库—mysql、数据库编程(API)

1. Linux平台准备 &#xff08;1&#xff09;安装SDK开发包的命令 sudo apt-get install libmysqlclient-dev &#xff08;2&#xff09;编译时需要链接的库:-lmysqlclient 2. mysql 的初始化和清理 #include <mysql/mysql.h> MYSQL mysql1; //创建句柄 mysql_init(&…

springboot+java高校图书馆图书借阅挂失崔还系统

功本次设计任务是要设计一个图书借阅系统&#xff0c;通过这个系统能够满足图书借阅系统的管理及用户的图书借阅功能。系统的主要功能包括&#xff1a;主页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;借阅证件管理&#xff0c;挂失信息管理&#xff0c;图书信息管理…

华为OD机试真题 JavaScript 实现【快速寻找某字符】【牛客练习题】

一、题目描述 给定一个一个目标值 target和一个 元素升序的无重复数字字符串 &#xff0c;写一个函数搜索 字符串 中的 target&#xff0c;如果目标值存在返回下标&#xff08;下标从 0 开始&#xff09;&#xff0c;否则返回 -1。 二、输入描述 第一行输入一个目标值target…

pullup和pulldown在verilog中的使用方法

0 前言 这段时间涉及到了IO-PAD&#xff0c;在IO-PAD的RTL的时候注意到了pullup和pulldown&#xff0c;对这个知识比较好奇&#xff0c;就研究了一下&#xff0c;顺便记录下来&#xff0c;IO-PAD的内容等我再研究研究再考虑记录吧 >_< 1 pullup和pulldown的介绍 pullu…

springboot3错误处理机制源码分析

ErrorMvcAutoConfiguration 在springboot启动时会自动装配默认的错误处理机制 ErrorMvcAutoConfiguration springboot正在运行&#xff0c;此时发生了404的错误。&#xff08;业务错误场景&#xff09;分析底层处理流程。 1.如果在对应的controller层中设置了对应的错误处理器…

【裸机开发】链接脚本(.lds文件)的基本语法

目录 一、什么是链接脚本&#xff1f; 二、链接脚本的基本语法格式 1、常用命令 2、内置变量 三、链接脚本的简单案例 一、什么是链接脚本&#xff1f; 一段程序的编译需要经历四个阶段&#xff08;预处理—编译—汇编—链接&#xff09;&#xff0c;而链接脚本管理的就是…

专业实习报告范本4篇

专业实习报告范本1 一、实习起止日期&#xff1a; 二、实习单位及部门&#xff08;岗位&#xff09;&#xff1a; 三、主要实习内容&#xff1a; 对基础知识和专业理论知识的掌握及运用情况&#xff1a; 通过两年半的学习和两个月的紧张培训&#xff0c;让我学会了电路图的分析…

彻底关闭 Win10 系统自动更新【四大步骤】

Windows 10 的自动更新非常顽固&#xff0c;多用户在网上试了各种关闭win10自动更新的方法&#xff0c;刚开始看着好像是关闭更新了&#xff0c;可没过多久系统就又开始自动更新了。今天笔者就来教大家如何彻底关闭win10自动更新&#xff0c;该方法亲测有效。 一、禁用 Window…

【AIGC】15、Grounding DINO | 将 DINO 扩展到开集目标检测

文章目录 一、背景二、方法2.1 特征抽取和加强2.2 Language-Guided Query Selection2.3 Cross-Modality Decoder2.4 Sub-sentence level text feature2.5 Loss Function 3、效果3.1 zero-shot transfer of grounding DINO3.2 Referring Object detection3.3 Ablations3.4 从 DI…

java springboot工程整合JUnit测试

好啦从此文开始 我们开始学习整合第三方技术的知识 后续 我们会整合一下第三方技术 后续也还会用到很多 但大家要学的是思想 而不是某某技术怎么去整合 当你会任何一种技术 你都能自如的整合到项目中 你才算掌握了整合技术 好 那么开始先整合 JUnit 我们打开idea 打开我们的 …

VC6创建工程的各种类型

各个工程类型的含义是什么&#xff1f; ATL COM AppWizard 用ATL技术制作COM程序&#xff0c;例如:WORD里面用的公式编辑器 ATL: Active Template Library活动模板库。ATL是COM的开发工具。 COM: 1993年Microsoft首次公布了COM技术. Wizard:向导 什么是ATL&#xff1f; &…

十分钟,零基础使用uniCloud完成后端管理系统搭建二

上一节我们已经成功搭建基础版的后端管理系统&#xff0c;这一节我们将利用uniCloud给我们提供的schema2code自动生成代码&#xff0c;快速完成&#xff1a;列表、增加和修改页面创建。 上一节&#xff1a; 十分钟&#xff0c;零基础使用uniCloud完成后端管理系统搭建一_szii…

图论算法 --Dijkstra

当谈到计算机科学时&#xff0c;算法是一个重要的话题&#xff0c;因为它们能帮助解决很多问题。而有些算法&#xff0c;其高效性和惊人表现&#xff0c;令人感到惊艳。一起来分享一下你认为令人惊艳的高效算法吧&#xff01; Dijkstra算法 一、你在工作和学习中用到过哪些惊艳…

半导体器件基础(期末模电速成)

目录 1、半导体分类 2、PN结 3、二极管 4、稳压二极管 5、三极管 6、场效应管 1、半导体分类 2、PN结 3、二极管 伏安特性&#xff1a; 我们第七版模电书上给的正向导通压降分别约为0.7和0.2V&#xff0c;且硅的单向导电性更好 如何确定二极管状态&#xff1f; 阳极电压…

C++ 输出格式控制

C 输出格式控制 需包含头文件&#xff1a; 浮点数精度、域宽、填充 操作符功能right-alignedright-alignedsetprecision(int n)设置以n表示的数值精度setw(int n)设置以n表示的域宽setfill(char c)设置以c表示的填充字符 输出格式 操作符功能oct以八进制格式输出数据dec以…

事件循环机制

基本概念 聊一下事件循环机制&#xff0c;在开始这篇文章之前&#xff0c;先明确一个概念&#xff0c;js本身是没有事件循环这个定义的。是js被嵌入相应的执行环境&#xff08;浏览器 / Nodejs&#xff09;&#xff0c;配合当前事件循环的组成部分&#xff0c;具体来说分下面两…

【基于容器的部署、扩展和管理】3.4 灰度发布和A/B测试

往期回顾&#xff1a; 第一章&#xff1a;【云原生概念和技术】 第二章&#xff1a;【容器化应用程序设计和开发】 第三章&#xff1a;【3.1 容器编排系统和Kubernetes集群的构建】 第三章&#xff1a;【3.2 基于容器的应用程序部署和升级】 第三章&#xff1a;【3.3 自动…

【C++】引用和右值引用

目录 1. 引用 1.1 引用的概念 1.2 引用的特性 1.3 引用的使用场景 1.3.1 作为参数 1.3.2 作为返回值 1.4 常量引用 1.5 引用和指针的区别 2. 左值和右值 3. 右值引用 3.1 右值引用的概念 3.2 左值持久&#xff1b;右值短暂 3.3 变量是左值 3.4 标准库move函数 1.…