Pozwólcie, że przeformatuję nieco twój przykład na potrzeby dyskusji:
long runCount = 0L;
myStream.stream()
.filter(...)
.forEach(item -> {
foo();
bar();
runCount++;
});
System.out.println("The lambda ran " + runCount + " times");
Jeśli naprawdę potrzebujesz zwiększyć licznik z poziomu lambdy, typowym sposobem na to jest ustawienie licznika na AtomicIntegeror, AtomicLonga następnie wywołanie jednej z metod inkrementacji.
Możesz użyć pojedynczego elementu intlub longtablicy, ale miałoby to warunki wyścigu, gdyby strumień był uruchamiany równolegle.
Ale zauważ, że strumień kończy się na forEach, co oznacza, że nie ma wartości zwracanej. Możesz zmienić na forEacha peek, który przekazuje elementy, a następnie je policzyć:
long runCount = myStream.stream()
.filter(...)
.peek(item -> {
foo();
bar();
})
.count();
System.out.println("The lambda ran " + runCount + " times");
To jest trochę lepsze, ale wciąż trochę dziwne. Powodem jest to forEachi peekmogą wykonywać swoją pracę tylko poprzez skutki uboczne. Wyłaniający się styl funkcjonalny Java 8 polega na unikaniu skutków ubocznych. Zrobiliśmy trochę tego, wyodrębniając przyrost licznika do countoperacji na strumieniu. Inne typowe skutki uboczne to dodawanie elementów do kolekcji. Zwykle można je wymienić za pomocą kolektorów. Ale nie wiedząc, jaką rzeczywistą pracę próbujesz wykonać, nie mogę zasugerować nic bardziej szczegółowego.