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 AtomicInteger
or, AtomicLong
a następnie wywołanie jednej z metod inkrementacji.
Możesz użyć pojedynczego elementu int
lub long
tablicy, 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 forEach
a 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 forEach
i peek
mogą 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 count
operacji 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.