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