从 01 开始 从 01 开始
首页
  • 📚 计算机基础

    • 计算机简史
    • 数字电路
    • 计算机组成原理
    • 操作系统
    • Linux
    • 计算机网络
    • 数据库
    • 编程工具
    • 装机
  • 🎨 前端

    • Node
  • JavaSE
  • Java 高级
  • JavaEE

    • 构建、依赖管理
    • Ant
    • Maven
    • 日志框架
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • 环境管理和配置管理-科普篇
    • Servlet
  • Spring

    • Spring基础
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC

    • SpringMVC 基础
  • SpringBoot

    • SpringBoot 基础
  • Windows 使用技巧
  • 手机
  • 最全面的输入法教程
  • 最全面的浏览器教程
  • Office
  • 图片类工具
  • 效率类工具
  • RSS
  • 码字工具
  • 各大平台
  • 校招
  • 五险一金等
  • 职场规划
  • 关于离职
  • 杂谈
  • 📖 读书

    • 读书工具
    • 读书笔记
  • 🌍 英语

    • 从零开始学英语
    • 英语兔的相关视频
    • Larry 想做技术大佬的相关视频
  • 🏛️ 政治

    • 反腐
    • GFW
    • 404 内容
    • 审查与自我审查
    • 互联网
    • 战争
  • 💰 经济

    • 关于税
    • 理财
  • 💪 健身

    • 睡眠
    • 皮肤
    • 口腔健康
    • 学会呼吸
    • 健身日志
  • 🏠 其他

    • 驾驶技能
    • 租房与买房
    • 厨艺
  • 电影

    • 电影推荐
  • 电视剧
  • 漫画

    • 漫画软件
    • 漫画推荐
  • 游戏

    • Steam
    • 三国杀
    • 求生之路
  • 小说
  • 关于本站
  • 关于博主
  • 打赏
  • 网站动态
  • 友人帐
  • 从零开始搭建博客
  • 搭建邮件服务器
  • 本站分享
  • 🌈 生活

    • 2022
    • 2023
    • 2024
    • 2025
  • 📇 文章索引

    • 文章分类
    • 文章归档

晓林

程序猿,自由职业者,博主,英语爱好者,健身达人
首页
  • 📚 计算机基础

    • 计算机简史
    • 数字电路
    • 计算机组成原理
    • 操作系统
    • Linux
    • 计算机网络
    • 数据库
    • 编程工具
    • 装机
  • 🎨 前端

    • Node
  • JavaSE
  • Java 高级
  • JavaEE

    • 构建、依赖管理
    • Ant
    • Maven
    • 日志框架
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • 环境管理和配置管理-科普篇
    • Servlet
  • Spring

    • Spring基础
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC

    • SpringMVC 基础
  • SpringBoot

    • SpringBoot 基础
  • Windows 使用技巧
  • 手机
  • 最全面的输入法教程
  • 最全面的浏览器教程
  • Office
  • 图片类工具
  • 效率类工具
  • RSS
  • 码字工具
  • 各大平台
  • 校招
  • 五险一金等
  • 职场规划
  • 关于离职
  • 杂谈
  • 📖 读书

    • 读书工具
    • 读书笔记
  • 🌍 英语

    • 从零开始学英语
    • 英语兔的相关视频
    • Larry 想做技术大佬的相关视频
  • 🏛️ 政治

    • 反腐
    • GFW
    • 404 内容
    • 审查与自我审查
    • 互联网
    • 战争
  • 💰 经济

    • 关于税
    • 理财
  • 💪 健身

    • 睡眠
    • 皮肤
    • 口腔健康
    • 学会呼吸
    • 健身日志
  • 🏠 其他

    • 驾驶技能
    • 租房与买房
    • 厨艺
  • 电影

    • 电影推荐
  • 电视剧
  • 漫画

    • 漫画软件
    • 漫画推荐
  • 游戏

    • Steam
    • 三国杀
    • 求生之路
  • 小说
  • 关于本站
  • 关于博主
  • 打赏
  • 网站动态
  • 友人帐
  • 从零开始搭建博客
  • 搭建邮件服务器
  • 本站分享
  • 🌈 生活

    • 2022
    • 2023
    • 2024
    • 2025
  • 📇 文章索引

    • 文章分类
    • 文章归档
  • JavaSE

    • 我的 Java 学习路线
    • 安装 Java
    • Java数据类型

    • Java 多版本配置
    • 面向对象

    • Java核心类

    • IO

    • Java与时间

    • 异常处理

    • 哈希和加密算法

    • Java8新特性

      • 函数式编程与 Lambda
      • Stream 介绍
      • 创建 Stream
        • Stream.of()
        • 基于数组或 Collection
        • 其他方法
        • 基本类型
        • 基于 Supplier
        • 练习
      • 操作 Stream
      • Optional
    • 网络编程

  • JavaSenior

  • JavaEE

  • JavaWeb

  • Spring

  • 主流框架

  • SpringMVC

  • SpringBoot

  • Java
  • JavaSE
  • Java8新特性
2023-03-13
目录

创建 Stream

# 创建 Stream

要使用 Stream,就必须先创建它。创建 Stream 有很多种方法,我们来一一介绍。

# Stream.of()

创建 Stream 最简单的方式是直接用 Stream.of() 静态方法,传入可变参数即创建了一个能输出确定元素的 Stream:

Stream<String> stream = Stream.of("A", "B", "C", "D");
stream.forEach(System.out::print);
1
2

输出:

ABCD
1

forEach() 方法相当于内部循环调用,可传入符合 Consumer 接口的 void accept(T t)的方法引用,例如 print。

这种方式基本上没啥实质性用途,但测试的时候很方便。

# 基于数组或 Collection

第二种创建 Stream 的方法是基于一个数组或者 Collection,这样该 Stream 输出的元素就是数组或者 Collection 持有的元素:

  • 把数组变成 Stream 使用 Arrays.stream() 方法。
  • 对于 Collection(List、Set、Queue 等),直接调用 stream() 方法就可以获得 Stream。
Stream<String> stream2 = Arrays.stream(new String[]{"A", "B", "C", "D"});
Stream<String> stream3 = Arrays.asList("A", "B", "C", "D").stream();
1
2

上述创建 Stream 的方法都是把一个现有的序列变为 Stream,它的元素是固定的。

# 其他方法

创建 Stream 的第三种方法是通过一些 API 提供的接口,直接获得 Stream。

例如,Files 类的 lines() 方法可以把一个文件变成一个 Stream,每个元素代表文件的一行内容:

try (Stream<String> lines = Files.lines(Paths.get("/path/to/file.txt"))) {
    ...
}
1
2
3

此方法对于按行遍历文本文件十分有用。

另外,正则表达式的 Pattern 对象有一个 splitAsStream() 方法,可以直接把一个长字符串分割成 Stream 序列而不是数组:

Pattern p = Pattern.compile("\\s+");
Stream<String> s = p.splitAsStream("The quick brown fox jumps over the lazy dog");
s.forEach(System.out::println);
1
2
3

# 基本类型

因为 Java 的范型不支持基本类型,所以我们无法用 Stream<int> 这样的类型,会发生编译错误。为了保存 int,只能使用 Stream<Integer>,但这样会产生频繁的装箱、拆箱操作。为了提高效率,Java 标准库提供了 IntStream、LongStream 和 DoubleStream 这三种使用基本类型的 Stream,它们的使用方法和范型 Stream 没有大的区别,设计这三个 Stream 的目的是提高运行效率:

// 将int[]数组变为IntStream:
IntStream is = Arrays.stream(new int[] { 1, 2, 3 });

// 将Stream<String>转换为LongStream:
LongStream ls = List.of("1", "2", "3").stream().mapToLong(Long::parseLong);
1
2
3
4
5

# 基于 Supplier

创建 Stream 还可以通过 Stream.generate() 方法,它需要传入一个 Supplier 对象:

Stream<String> s = Stream.generate(Supplier<String> sp);
1

基于 Supplier 创建的 Stream 会不断调用 Supplier.get() 方法来不断产生下一个元素,这种 Stream 保存的不是元素,而是算法,它可以用来表示无限序列。

例如,我们编写一个能不断生成自然数的 Supplier,它的代码非常简单,每次调用 get() 方法,就生成下一个自然数:

import java.util.function.*;
import java.util.stream.*;
public class Main {
    public static void main(String[] args) {
        Stream<Integer> natual = Stream.generate(new NatualSupplier());
        // 注意:无限序列必须先变成有限序列再打印:
        natual.limit(20).forEach(System.out::println);
    }
}

class NatualSupplier implements Supplier<Integer> {
    int n = 0;
    public Integer get() {
        n++;
        return n;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

上述代码我们用一个 Supplier<Integer> 模拟了一个无限序列(当然受 int 范围限制不是真的无限大)。如果用 List 表示,即便在 int 范围内,也会占用巨大的内存,而 Stream 几乎不占用空间,因为每个元素都是实时计算出来的,用的时候再算。

对于无限序列,如果直接调用 forEach() 或者 count() 这些最终求值操作,会进入死循环,因为永远无法计算完这个序列,所以正确的方法是先把无限序列变成有限序列,例如,用 limit() 方法可以截取前面若干个元素,这样就变成了一个有限序列,对这个有限序列调用 forEach() 或者 count() 操作就没有问题。

# 练习

编写一个能输出斐波拉契数列(Fibonacci)的 LongStream:

1, 1, 2, 3, 5, 8, 13, 21, 34, ...
1

提示:使用 Supplier

上次更新: 2024/10/1 17:11:02
Stream 介绍
操作 Stream

← Stream 介绍 操作 Stream→

最近更新
01
吐槽一下《僵尸校园》
05-15
02
2025 年 4 月记
04-30
03
山西大同 “订婚强奸案” 将会给整个社会带来的影响有多严重? - 知乎 转载
04-26
更多文章>
Theme by Vdoing | Copyright © 2022-2025 | 粤 ICP 备 2022067627 号 -1 | 粤公网安备 44011302003646 号 | 点击查看十年之约
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式