Điều này là có thể cho Iterable.forEach()
(nhưng không đáng tin cậy với Stream.forEach()
). Giải pháp là không tốt đẹp, nhưng nó là có thể.
CẢNH BÁO : Bạn không nên sử dụng nó để kiểm soát logic kinh doanh, mà hoàn toàn để xử lý một tình huống đặc biệt xảy ra trong quá trình thực thi forEach()
. Chẳng hạn như tài nguyên đột nhiên dừng truy cập, một trong các đối tượng được xử lý đang vi phạm hợp đồng (ví dụ: hợp đồng nói rằng tất cả các yếu tố trong luồng không được null
nhưng đột nhiên và bất ngờ một trong số chúng lànull
) v.v.
Theo tài liệu cho Iterable.forEach()
:
Thực hiện hành động đã cho cho từng phần tử của Iterable
cho đến khi tất cả các phần tử đã được xử lý hoặc hành động đưa ra một ngoại lệ ... Các ngoại lệ được ném bởi hành động được chuyển tiếp đến người gọi.
Vì vậy, bạn ném một ngoại lệ sẽ ngay lập tức phá vỡ vòng lặp nội bộ.
Mã sẽ giống như thế này - tôi không thể nói tôi thích nó nhưng nó hoạt động. Bạn tạo lớp riêng của bạn BreakException
mà mở rộng RuntimeException
.
try {
someObjects.forEach(obj -> {
// some useful code here
if(some_exceptional_condition_met) {
throw new BreakException();
}
}
}
catch (BreakException e) {
// here you know that your condition has been met at least once
}
Lưu ý rằng không phảitry...catch
là xung quanh biểu thức lambda, mà là xung quanh toàn bộ phương thức. Để làm cho nó rõ hơn, hãy xem bản phiên mã sau đây cho thấy rõ hơn:forEach()
Consumer<? super SomeObject> action = obj -> {
// some useful code here
if(some_exceptional_condition_met) {
throw new BreakException();
}
});
try {
someObjects.forEach(action);
}
catch (BreakException e) {
// here you know that your condition has been met at least once
}
for
tuyên bố thực sự .