怎么通过 Stream.iterate() 生成一个斐波那契数列的数据流并进行后续的截取处理
利用Java8的Stream.iterate(),以初始数组[0,1](存储相邻两项)为种子,通过迭代函数生成下一对,再用map提取首项得到斐波那契数列,用limit()或takeWhile()截取有限项。为防止溢出可改用BigInteger。此流式方法非常简洁高效,避免了传统循环或递归的繁琐。
先来看一个经典的面试题:怎么用 Ja va 8 的 Stream.iterate() 生成斐波那契数列,并且还能做后续的截取处理?这事儿其实挺有意思的,因为斐波那契本身就依赖前两项的值,而 iterate() 默认只给一个种子——所以得动点脑筋。

核心思路是:把“一对相邻项”作为整个迭代的状态载体,每次根据这两项推算出下一对,然后滑动窗口往前走。这样一来,每一步生成的都是一个长度为2的数组,索引0是当前的斐波那契数,索引1是下一个。
用二元元组作为状态载体
既然斐波那契数列依赖前两项,那我们就别只传一个数字了——传一个 new long[]{0, 1} 数组过去,迭代函数里基于当前两项算出下一项:
- 起始种子:
new long[]{0, 1} - 迭代函数:
prev -> new long[]{prev[1], prev[0] + prev[1]} - 这样每一步都得到新的
[Fₙ, Fₙ₊₁],流中每个元素是长度为2的数组
提取首项并截取有限项
我们真正想要的是数列本身(每个 Fₙ),所以需要从每对数组中提取第一个值,用 map 搞定;接着用 limit(n) 截取前 n 项,完美收工:
Stream.iterate(new long[]{0, 1},
prev -> new long[]{prev[1], prev[0] + prev[1]})
.map(pair -> pair[0])
.limit(10)
.forEach(System.out::println); // 输出前10个斐波那契数:0,1,1,2,3,5,8,13,21,34
避免整数溢出(可选增强)
如果项数稍微多一点,long 类型就会溢出。这时候可以考虑换用 BigInteger,逻辑完全一样,只是把数据类型换掉:
- 种子:
new BigInteger[]{BigInteger.ZERO, BigInteger.ONE} - 迭代函数:
prev -> new BigInteger[]{prev[1], prev[0].add(prev[1])} - 后续的
map和limit保持不变
注意终止条件与无限流特性
有一点容易忽略:iterate() 默认生成的是无限流,必须显式用 limit() 或 takeWhile() 等中间操作截断,否则终端操作(比如 forEach)会无限执行下去。举个例子,如果希望按值大小截断,可以这样写:
.takeWhile(f -> f <= 1000)
这样只会输出所有 ≤1000 的斐波那契数(0,1,1,2,...,987),既避免了溢出风险,又不用提前指定项数。灵活又优雅,不是吗?


































