商城首页欢迎来到中国正版软件门户

您的位置: 首页 > 文章列表 > 编程开发 > 怎么通过 Stream.iterate() 生成一个斐波那契数列的数据流并进行后续的截取处理

怎么通过 Stream.iterate() 生成一个斐波那契数列的数据流并进行后续的截取处理

  发布于2026-07-08 阅读(0)

扫一扫,手机访问

先来看一个经典的面试题:怎么用 Ja va 8 的 Stream.iterate() 生成斐波那契数列,并且还能做后续的截取处理?这事儿其实挺有意思的,因为斐波那契本身就依赖前两项的值,而 iterate() 默认只给一个种子——所以得动点脑筋。

怎么通过 Stream.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])}
  • 后续的 maplimit 保持不变

注意终止条件与无限流特性

有一点容易忽略:iterate() 默认生成的是无限流,必须显式用 limit()takeWhile() 等中间操作截断,否则终端操作(比如 forEach)会无限执行下去。举个例子,如果希望按值大小截断,可以这样写:

.takeWhile(f -> f <= 1000)

这样只会输出所有 ≤1000 的斐波那契数(0,1,1,2,...,987),既避免了溢出风险,又不用提前指定项数。灵活又优雅,不是吗?

本文转载于:https://www.php.cn/faq/2424306.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注