Permíteme reformatear un poco tu ejemplo por el bien de la discusión:
long runCount = 0L;
myStream.stream()
.filter(...)
.forEach(item -> {
foo();
bar();
runCount++;
});
System.out.println("The lambda ran " + runCount + " times");
Si realmente necesita incrementar un contador desde dentro de una lambda, la forma típica de hacerlo es convertir el contador en AtomicIntegero AtomicLongy luego llamar a uno de los métodos de incremento en él.
Podría usar un elemento único into una longmatriz, pero eso tendría condiciones de carrera si la transmisión se ejecuta en paralelo.
Pero observe que el flujo termina en forEach, lo que significa que no hay valor de retorno. Puede cambiar forEacha a peek, que pasa los elementos y luego contarlos:
long runCount = myStream.stream()
.filter(...)
.peek(item -> {
foo();
bar();
})
.count();
System.out.println("The lambda ran " + runCount + " times");
Esto es algo mejor, pero todavía un poco extraño. La razón es que forEachy peeksolo pueden hacer su trabajo a través de efectos secundarios. El estilo funcional emergente de Java 8 es evitar efectos secundarios. Hicimos un poco de eso extrayendo el incremento del contador en una countoperación en la secuencia. Otros efectos secundarios típicos son la adición de elementos a las colecciones. Por lo general, estos se pueden reemplazar mediante el uso de colectores. Pero sin saber qué trabajo real está tratando de hacer, no puedo sugerir nada más específico.