Дозвольте трохи переформатувати ваш приклад задля обговорення:
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операцію на потоці. Іншими типовими побічними ефектами є додавання предметів до колекцій. Зазвичай їх можна замінити за допомогою колекторів. Але, не знаючи, яку реальну роботу ви намагаєтесь виконати, я не можу запропонувати нічого більш конкретного.