Hãy để tôi định dạng lại ví dụ của bạn một chút để tiện cho việc thảo luận:
long runCount = 0L;
myStream.stream()
.filter(...)
.forEach(item -> {
foo();
bar();
runCount++;
});
System.out.println("The lambda ran " + runCount + " times");
Nếu bạn thực sự cần tăng một bộ đếm từ bên trong lambda, cách thông thường để làm như vậy là tạo bộ đếm là một AtomicIntegerhoặc AtomicLongvà sau đó gọi một trong các phương thức tăng trên đó.
Bạn có thể sử dụng một phần tử inthoặc longmảng đơn lẻ , nhưng điều đó sẽ có các điều kiện về chủng tộc nếu luồng được chạy song song.
Nhưng lưu ý rằng luồng kết thúc bằng forEach, có nghĩa là không có giá trị trả về. Bạn có thể thay đổi forEachthành a peek, chuyển các mục đi qua, sau đó đếm chúng:
long runCount = myStream.stream()
.filter(...)
.peek(item -> {
foo();
bar();
})
.count();
System.out.println("The lambda ran " + runCount + " times");
Điều này có phần tốt hơn, nhưng vẫn hơi kỳ quặc. Lý do là forEachvà peekchỉ có thể làm công việc của họ thông qua các tác dụng phụ. Phong cách chức năng mới nổi của Java 8 là để tránh các tác dụng phụ. Chúng tôi đã thực hiện một chút điều đó bằng cách trích xuất số gia của bộ đếm thành một counthoạt động trên luồng. Các tác dụng phụ điển hình khác là thêm các mục vào bộ sưu tập. Thông thường chúng có thể được thay thế bằng cách sử dụng bộ sưu tập. Nhưng không biết công việc thực tế bạn đang cố gắng làm là gì, tôi không thể đề xuất điều gì cụ thể hơn.