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 AtomicInteger
o AtomicLong
y luego llamar a uno de los métodos de incremento en él.
Podría usar un elemento único int
o una long
matriz, 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 forEach
a 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 forEach
y peek
solo 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 count
operació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.