发布于2026-07-09 阅读(0)
扫一扫,手机访问
Stream.generate() 能生成恒定值流,这个不难理解,但背后到底怎么工作的?说白了,它的入参是 Supplier,每次被调用时都会执行一次 get() 方法并返回一个新值。当这个 Supplier 每次都返回同一个对象(或基本类型值)时,整个流自然就表现为“恒定值流”。注意,这里的关键不是“只生成一次”,而是“每次都生成相同结果”——这个区别很重要。

那具体怎么写呢?最简写法其实一行 Lambda 就够了:
Stream.generate(() -> "test")
这样会持续产出 "test" 字符串。但有个前提:不加限制会无限运行。所以实际使用时,必须配合 limit() 或其他终止操作:
Stream.generate(() -> 42).limit(5).toList() → [42, 42, 42, 42, 42]Stream.generate(() -> new User("mock")).limit(3).collect(Collectors.toList()) → 三个独立的 User 实例(注意,这里每次都是新对象,不是引用复用)不过,使用过程中也有容易踩坑的地方。比如下面这段代码,看似省事,实则危险:
User user = new User("shared");
Stream.generate(() -> user).limit(3).forEach(System.out::println);
它确实输出了三个一样的 User,但它们是同一个对象引用。如果后续流中对对象做了修改(比如调用了 user.setName("changed")),所有元素都会跟着变。真正安全的做法是每次构造新实例:
Stream.generate(() -> new User("mock"))Stream.generate(() -> user)(除非你明确需要共享引用)String、Integer)可以安全复用,因为无法被修改有人可能会把 Stream.generate() 和 Stream.iterate() 搞混。关键差异在于“状态依赖”:
generate() 是无状态的,每次调用 Supplier.get() 都是干净的、不依赖前一次结果。iterate() 则是有状态的,后一个元素由前一个计算得出(比如 Stream.iterate(0, n -> n + 1))。generate() 更自然。如果想用 iterate() 实现“从某值开始、一直不变”,反而得绕弯子:Stream.iterate("fixed", s -> s) —— 不推荐。恒定值流本身并不复杂,但对象生命周期和引用语义容易被忽略。尤其在测试中用 new 构造对象时,别图快直接复用变量。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8