Java 8:计算 lambda 迭代次数的首选方法?

2024-01-07

我经常面临同样的问题。我需要计算 a 的运行次数lambda供外部使用lambda.

E.g.:

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");

If you really需要从 lambda 中增加计数器,典型的方法是将计数器设为AtomicInteger or AtomicLong然后对其调用增量方法之一。

您可以使用单个元素int or long数组,但如果流并行运行,则会出现竞争条件。

但请注意,流结束于forEach,这意味着没有返回值。你可以改变forEach to a peek,它传递项目,然后对它们进行计数:

long runCount = myStream.stream()
    .filter(...)
    .peek(item -> { 
        foo();
        bar();
    })
    .count();
System.out.println("The lambda ran " + runCount + " times");

这稍微好一些,但仍然有点奇怪。原因是forEach and peek只能通过副作用来发挥作用。 Java 8 新兴的函数式风格是为了避免副作用。我们通过将计数器的增量提取到一个count对流进行操作。其他典型的副作用是将项目添加到集合中。通常这些可以通过使用收集器来替换。但在不知道你想要做什么实际工作的情况下,我无法提出更具体的建议。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java 8:计算 lambda 迭代次数的首选方法? 的相关文章

随机推荐