作者热门文章
- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我经常遇到同样的问题。我需要计算 lambda 的运行次数,以便在 lambda 之外使用。
例如:
myStream.stream().filter(...).forEach(item -> { ... ; runCount++});
System.out.println("The lambda ran " + runCount + "times");
问题是 runCount 需要是 final
,所以它不能是 int
。它不能是Integer
,因为它是不可变的。我可以将其设为类级别变量(即字段),但我只需要在这段代码中使用它。
我知道有多种方法,我只是想知道您的首选解决方案是什么?
您是使用 AtomicInteger
还是数组引用或其他方式?
最佳答案
为了便于讨论,让我重新格式化您的示例:
long runCount = 0L;
myStream.stream()
.filter(...)
.forEach(item -> {
foo();
bar();
runCount++; // doesn't work
});
System.out.println("The lambda ran " + runCount + " times");
如果您真的需要在 lambda 中增加一个计数器,典型的做法是使计数器成为 AtomicInteger
或 AtomicLong
然后调用其中一个增量方法。
您可以使用单元素 int
或 long
数组,但如果流并行运行,则会出现竞争条件。
但请注意,流以 forEach
结尾,这意味着没有返回值。您可以将 forEach
更改为 peek
,它会传递项目,然后计算它们:
long runCount = myStream.stream()
.filter(...)
.peek(item -> {
foo();
bar();
})
.count();
System.out.println("The lambda ran " + runCount + " times");
这有点好,但还是有点奇怪。原因是 forEach
和 peek
只能通过副作用来完成它们的工作。 Java 8 新兴的函数式风格是为了避免副作用。我们通过将计数器的增量提取到流上的 count
操作中做了一点。其他典型的副作用是将项目添加到集合中。通常这些可以通过使用收集器来替换。但在不知道您要做什么实际工作的情况下,我无法提出更具体的建议。
关于Java 8 : preferred way to count iterations of a lambda?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28790784/
我是一名优秀的程序员,十分优秀!