Java 如何在Collections.forEach()中打印计数

Java 如何在Collections.forEach()中打印计数,java,java-8,Java,Java 8,下面是一个列表,使用lambda表达式: ArrayList<String> array = new ArrayList<>(); ... StringBuffer buf = new StringBuffer(""); array.stream().forEach((item) -> { buf.append("Counter here: " + item.toString() + "\n"); }); return buf.toString(); Ar

下面是一个列表,使用lambda表达式:

ArrayList<String> array = new ArrayList<>();
...
StringBuffer buf = new StringBuffer("");
array.stream().forEach((item) -> {
    buf.append("Counter here: " + item.toString() + "\n");
});
return buf.toString();
ArrayList数组=新的ArrayList();
...
StringBuffer buf=新的StringBuffer(“”);
array.stream().forEach((项)->{
buf.append(“此处计数器:“+item.toString()+”\n”);
});
返回buf.toString();
但是我不能实例化和修改
forEach
lambda表达式中的变量,因为它必须是
final
。有什么方法可以做到这一点吗?

为此使用原子学:

AtomicInteger cnt = new AtomicInteger(0);
StringBuilder buf = new StringBuilder("");
array.stream().forEach((item) -> {
    buf.append("Counter here: " + cnt.incrementAndGet() + "\n");
});
return buf.toString();

使用大小为1的
int[]
作为计数器:

ArrayList<String> array = new ArrayList<>();
int[] count = {0};
return array.stream().map(item -> count[0]++ + ":" + item)
  .collect(Collectors.joining("\n", "", "\n"));
ArrayList数组=新的ArrayList();
int[]计数={0};
return array.stream().map(项->计数[0]+++“:“+项)
.collect(收集器.joining(“\n”、”、“\n”);
int[]
实际上是最终的。它的内容不一定是


请注意,如果使用
joining()
收集器,您甚至不需要
StringBuilder

我不明白。您想要每个元素的索引吗?是的,或者在apache lang中只需要像“0:…”和“1:…”这样的计数器,它的开销比AtomicInteger少。另外,请避免使用StringBuffer作为局部变量使用StringBuilder(StringBuffer是同步的,StringBuilder不是,除非您要使用多个线程更新该缓冲区,否则您将承担额外的成本而没有任何好处)。
我希望有一个功能,允许人们在答案中标记“无用”的位置当向下投票时,
我希望版主和Java金牌持有者能够投票适当地关闭副本。
@Pillar-hmmm,这个答案不在dupe中,但可以……政策不是在那里添加答案,而不是关闭dupe问题吗?无论如何,你应该考虑这样的答案不存在的一个很好的理由……这个代码会不会产生错误,使<代码> BUF <代码>最终< /代码>或有效的???@ LaliRao <代码> CNT< /COD>和<代码> BUF最终是有效的,这里没有错误。它可以在Java8上正常工作。你能详细解释一下吗?我的意思是,我们正在改变lambda内部的
buf
状态,对吗?那个么,它是如何有效地保持最终状态的呢?@LalitRao简单地说:您可以修改从lambda表达式引用的对象的内部状态。但是不允许您自己更改对象引用,例如
buf.toString()
cnt.incrementAndGet()
是允许的,但是
buf=buf.append(“test”)
或例如
i=i+1
i++
没有得到很好的解释