Lassen Sie mich Ihr Beispiel zur Diskussion ein wenig neu formatieren:
long runCount = 0L;
myStream.stream()
.filter(...)
.forEach(item -> {
foo();
bar();
runCount++;
});
System.out.println("The lambda ran " + runCount + " times");
Wenn Sie einen Zähler wirklich aus einem Lambda heraus inkrementieren müssen, besteht die typische Methode darin, den Zähler zu einem AtomicIntegeroder zu machen AtomicLongund dann eine der Inkrementierungsmethoden darauf aufzurufen.
Sie könnten ein einzelnes Element intoder longArray verwenden, dies hätte jedoch Race-Bedingungen, wenn der Stream parallel ausgeführt wird.
Beachten Sie jedoch, dass der Stream endet forEach, was bedeutet, dass es keinen Rückgabewert gibt. Sie können das forEachin a ändern peek, das die Elemente durchläuft, und sie dann zählen:
long runCount = myStream.stream()
.filter(...)
.peek(item -> {
foo();
bar();
})
.count();
System.out.println("The lambda ran " + runCount + " times");
Das ist etwas besser, aber immer noch etwas seltsam. Der Grund ist, dass forEachund peekkönnen ihre Arbeit nur über Nebenwirkungen erledigen. Der aufkommende Funktionsstil von Java 8 besteht darin, Nebenwirkungen zu vermeiden. Wir haben ein wenig davon getan, indem wir das Inkrement des Zählers in eine countOperation im Stream extrahiert haben . Andere typische Nebenwirkungen sind das Hinzufügen von Elementen zu Sammlungen. In der Regel können diese durch Verwendung von Kollektoren ersetzt werden. Aber ohne zu wissen, welche Arbeit Sie tatsächlich versuchen, kann ich nichts Spezifischeres vorschlagen.