Позвольте мне немного переформатировать ваш пример для обсуждения:
long runCount = 0L;
myStream.stream()
.filter(...)
.forEach(item -> {
foo();
bar();
runCount++;
});
System.out.println("The lambda ran " + runCount + " times");
Если вам действительно нужно увеличить счетчик из лямбды, типичный способ сделать это - сделать счетчик AtomicIntegerилиAtomicLong а затем вызвать для него один из методов увеличения.
Вы можете использовать одноэлементный intилиlong массив, но это будет иметь условия гонки, если поток будет выполняться параллельно.
Но обратите внимание, что поток заканчивается forEach, а это означает, что возвращаемого значения нет. Вы можете изменить на forEacha peek, который передает элементы, а затем подсчитывает их:
long runCount = myStream.stream()
.filter(...)
.peek(item -> {
foo();
bar();
})
.count();
System.out.println("The lambda ran " + runCount + " times");
Это немного лучше, но все же немного странно. Причина заключается в том, что forEachи peekможет сделать только свою работу с помощью побочных эффектов. Новый функциональный стиль Java 8 призван избежать побочных эффектов. Мы немного поработали, извлекая приращение счетчика в countоперацию в потоке. Другими типичными побочными эффектами являются добавление элементов в коллекции. Обычно их можно заменить с помощью коллекторов. Но, не зная, какую реальную работу вы пытаетесь выполнить, я не могу предложить ничего более конкретного.