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 AtomicInteger
hoặc AtomicLong
và 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ử int
hoặc long
mả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 forEach
thà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à forEach
và peek
chỉ 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 count
hoạ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.