我可以在使用Iterable.forEach(Consumer)进行迭代时更改元素吗?

时间:2019-04-25 17:07:19

标签: java foreach iterable

在使用Iterable.forEach(Consumer)迭代元素时可以更改元素吗?还是在Consumer.accept(E)中,我只能读取底层Iterable的元素,而不能更改它们?

如果我可以更改它们,正确的语法是什么?

ArrayDeque d = new ArrayDeque<Integer>();
d.add(1);
d.add(2);
d.add(3);
d.add(4);

Consumer<Integer> cons = (e)->{e = e*10;}; // compiles!

d.forEach(cons);

System.out.println(d); // 1 2 3 4 not 10 20 30 40

4 个答案:

答案 0 :(得分:2)

您要执行的操作与以下操作相同:

for (Integer e : d) {
   e = e * 10;
}

但是分配给e不会改变双端队列的值。

要做你想做的,

 d = d.stream().map(a -> a * 10).collect(
            Collectors.toCollection(ArrayDeque::new));
 System.out.println(d);

答案 1 :(得分:1)

forEach的Consumer参数不返回任何内容,根据您的示例,每个e都是ArrayDeque中元素的副本,因此您不能使用{{ 1}}。

如果您要对一个任务的每个元素执行forEach(例如打印它们),则可以将e*10转换为ArrayDeque,并使用map():

Stream

这样做将显示双端队列中的每个元素都乘以10。

如果您想实际替换d.stream().map(e -> e*10).forEach(e -> System.out.println(e)); 中的元素,

ArrayDeque

答案 2 :(得分:1)

不,您不能在使用forEach时修改元素,因为action的值是Consumer,而acceptsforEachdefault void forEach(Consumer<? super T> action) for (T t : this) action.accept(t); 方法的示例代码段

{{1}}

主要要注意的是它不会产生任何值。

答案 3 :(得分:1)

不,您不能。根据{{​​3}}:

  

此类的迭代器方法返回的迭代器是快速失败的:如果在创建迭代器后的任何时间修改了双端队列,则除了通过迭代器自己的remove方法之外,该迭代器通常会抛出documentation for ArrayDeque