【发布时间】:2015-06-07 13:16:59
【问题描述】:
我想使用 lambda 表达式而不是 for 循环来生成数字列表。
假设我想生成一个所有小于 100 的三角数的列表。三角数是遵循以下公式的数:(n*n+n)/2
这样做的最佳方法是什么? 目前我有这个:
Stream.iterate(1, n -> n + 1).limit(100)
.map(n -> (n * n + n) / 2)
.filter(a -> a < 100)
.map(a -> a + "")
.collect(Collectors.joining(", ", "Numbers: ", "."));
但这对于计算量来说似乎是不必要的。我将 n 从 1 迭代到 100(因为假设我不知道 n 的最大值是多少),然后我映射该列表的三角形数函数,然后检查哪些数字低于 100。有没有更有效的方法在这样做? 另外:我可以只使用Stream的迭代函数而不是使用迭代、限制然后映射来生成三角形数吗?
编辑: 所以这里的重点是:三角形数中的一个一超过100,怎么会停止计算? 通常我会这样写:
ArrayList<Integer> triangles = new ArrayList<>();
for (int n=1;true;n++) {
int num = (n*n+n)/2;
if (num>100) break;
triangles.add(num);
}
三角形数一超过100就停止,效率很高;如何在 lambda 表达式中保持这种效率?
【问题讨论】:
-
Stream.iterate(1, n->n+1).limit(100)可以重写为IntStream.rangeClosed(1, 100),这可能更具可读性。 -
你为什么同时使用限制和过滤器?我相信第二个过滤器会根据计算限制输出,所以你只会得到小于 100 的结果,而不是小于 100 的输入。
-
重点是什么?还是只是好奇?