为了账号安全,请及时绑定邮箱和手机立即绑定

我使用 IntStream 和 forEach 创建整数列表的方法有什么问题?

我使用 IntStream 和 forEach 创建整数列表的方法有什么问题?

噜噜哒 2022-01-06 17:27:43
我的天真代码是:class ${    public static void main(String[] _) {        final List<Integer> ints = new ArrayList<>();        IntStream.iterate(0, i -> i++).limit(5).forEach(val -> ints.add(val));        System.out.println(ints);    }}我的期望是在控制台中看到以下内容:[0, 1, 2, 3, 4]但实际情况是:[0, 0, 0, 0, 0]这可能是非常简单的事情,但我错过了什么?
查看完整描述

3 回答

?
慕丝7291255

TA贡献1859条经验 获得超6个赞

i++i 增加之前的值为。您需要使用前缀运算符。

IntStream.iterate(0, i -> ++i).limit(5).forEach(val -> ints.add(val));

实际上,不要那样做。没有理由 mutate i,它只是被扔掉了。使用副作用免费版本。毕竟,这就是函数式编程背后的全部思想:避免副作用。

IntStream.iterate(0, i -> i + 1).limit(5).forEach(val -> ints.add(val));

对于连续整数流的特定情况,您可以将iterate和替换limitrange

IntStream.range(0, 5).forEach(val -> ints.add(val));

最后,最好将流收集到列表中,而不是使用forEach. 它直接表达了创建列表的意图,再次避免了副作用。

List<Integer> ints = IntStream.range(0, 5).boxed().collect(Collectors.toList());


查看完整回答
反对 回复 2022-01-06
?
扬帆大鱼

TA贡献1799条经验 获得超9个赞

在将值传递给 时i++,您使用的是后缀而不是前缀。更改为以下内容将为您提供预期的输出:++iforEach

IntStream.iterate(0, i -> i + 1).limit(5).forEach(ints::add);

一边,迭代和组合与Java9 +限制的替代方法是使用IntStream.iterate具有IntPredicate如:

IntStream.iterate(0, i -> i < 5, i -> i + 1).forEach(ints::add);


查看完整回答
反对 回复 2022-01-06
?
狐的传说

TA贡献1804条经验 获得超3个赞

您需要返回增加的值。您后缀增加了一个局部变量并返回了未增加的值。++i不使用i++


final List<Integer> ints = new ArrayList<>();

IntStream.iterate(0, i -> ++i).limit(5).forEach(val -> ints.add(val));

System.out.println(ints);

编辑请参阅 John Kugelman 关于在以函数式风格编程时使用非变异操作的帖子。使用i + 1将创建一个新的原语,而不是改变参数变量。


查看完整回答
反对 回复 2022-01-06
  • 3 回答
  • 0 关注
  • 170 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信