2009-02-15 79 views
29

Tôi có bốn vòng foreach lặp đi lặp lại thông qua các bộ sưu tập và dựa trên một điều kiện làm điều gì đó. Đây là mã mà tôi đang viết bây giờ:Làm thế nào để phá vỡ nhiều vòng lặp foreach?

boolean breakFlag = false; 
String valueFromObj2 = null; 
String valueFromObj4 = null; 
for(Object1 object1: objects){ 
    for(Object2 object2: object1){ 
    //I get some value from object2 
    valueFromObj2 = object2.getSomeValue(); 
    for(Object3 object3 : object2){ 
     for(Object4 object4: object3){ 
     //Finally I get some value from Object4. 
     valueFromObj4 = object4.getSomeValue(); 
     //Compare with valueFromObj2 to decide either to break all the foreach loop 
     breakFlag = compareTwoVariable(valueFromObj2, valueFromObj4); 
     if(breakFlag){break;} 
     }//fourth loop ends here 
     if(breakFlag){break;} 
    }//third loop ends here 
    if(breakFlag){break;} 
    }//second loop ends here 
    if(breakFlag){break;} 
}//first loop ends here 

Đối tượng chính (đối tượng trong mã) đến từ nhà cung cấp bên thứ ba SDK, vì vậy tôi không thể thay đổi bất cứ điều gì trên phần đó. Tôi muốn hỏi cộng đồng stackoverflow nếu có một cách tiếp cận tốt hơn để phá vỡ tất cả bốn vòng lặp foreach. Hoặc nếu có cách nào khác để cấu trúc lại mã này để làm cho nó dễ đọc hơn và dễ bảo trì hơn. Cảm ơn.

+0

Btw, đó là * cho * không * foreach *. –

+3

Không, cho (Object o: os) thực sự được gọi là vòng lặp foreach hoặc iterator. – Esko

+0

Phiên bản gốc có "foreach" trong chính mã. Cảm ơn bạn đã chỉnh sửa. – royalGhost

Trả lời

78

Sử dụng nhãn trên vòng ngoài cùng và bao gồm nhãn này trong câu lệnh break khi bạn muốn thoát khỏi tất cả các vòng lặp. Trong ví dụ bên dưới, tôi đã sửa đổi mã của bạn để sử dụng nhãn OUTERMOST:

String valueFromObj2 = null; 
String valueFromObj4 = null; 
OUTERMOST: for(Object1 object1: objects){ 
    for(Object2 object2: object1){ 
    //I get some value from object2 
    valueFromObj2 = object2.getSomeValue(); 
    for(Object3 object3 : object2){ 
     for(Object4 object4: object3){ 
     //Finally I get some value from Object4. 
     valueFromObj4 = object4.getSomeValue(); 
     //Compare with valueFromObj2 to decide either to break all the foreach loop 
     if(compareTwoVariable(valueFromObj2, valueFromObj4)) { 
      break OUTERMOST; 
     } 
     }//fourth loop ends here 
    }//third loop ends here 
    }//second loop ends here 
}//first loop ends here 
+4

Đây là câu trả lời đúng cho câu hỏi của tôi. Nhưng, tôi tái cấu trúc giống như những người khác đã đề xuất và chuyển logic sang một hàm nhỏ và sử dụng "return". – royalGhost

+0

Chỉ sử dụng nhãn Chức năng chỉ khi bạn không có giải pháp khác. Không phải là một thực hành tốt. – lucasddaniel

0

Ném ngoại lệ và bắt nó bên ngoài vòng lặp? Sử dụng thứ gì đó "được coi là có hại?"

Đó là một chút hài hước khi khoa học máy tính vẽ mình thành một góc ;-)

+3

"Khoa học máy tính" không "tự vẽ thành một góc". Nhưng đôi khi các lập trình viên đưa ra những lựa chọn hoặc giả định ban đầu để hạn chế các lựa chọn của họ sau này. –

+2

Tôi nghĩ tôi rất vui. Kết quả có thể thay đổi. – dwc

+0

Kết quả có thể thay đổi. rofl. –

1

Một cách để phá vỡ, hoặc thu gọn một vài câu lệnh (trên thực tế ngăn xếp khung) là để ném một ngoại lệ nhưng điều này là không nên vì nó thực sự tốn kém cho thời gian chạy để thư giãn ngăn xếp và nó có thể dẫn đến thực sự khó khăn khó khăn để gỡ lỗi hành vi không xác định, (giữ điều này trong tâm trí).

Nếu không, tôi khuyên bạn nên viết lại mã đó để có thể thoát khỏi vòng lặp một cách duyên dáng. Nếu bạn không thể thay đổi mã này theo bất kỳ cách nào khác, thì bạn sẽ phải dẫn đến ngoại lệ ...

+0

Java không hỗ trợ nhãn, nhưng chúng chỉ có thể được sử dụng với các câu lệnh ngắt và tiếp tục. –

19

Trích xuất tất cả các vòng vào hàm và sử dụng trả về.

+0

Mã như được hiển thị không tốt đẹp: việc tái cấu trúc dọc theo các dòng này sẽ tốt hơn nhiều. – Fortyrunner

+2

đây là cách ưa thích hơn khi sử dụng các nhãn ngắt, trừ khi bạn biết rõ ràng hơn là sử dụng ngắt. – Chii

+0

Giới thiệu ranh giới phương pháp ở một vị trí tùy ý là "cách ưu tiên"? –

6

Bạn có thể sử dụng câu lệnh ngắt có gắn nhãn. Loại break ngắt một tuyên bố bên ngoài

Xem The break Statement

0

Giải pháp đơn giản là đặt toàn bộ quá trình tìm kiếm trong một phương pháp và return ngay sau khi bạn có một câu trả lời.

Tuy nhiên, dạng trừu tượng của mã mẫu của bạn để lại một số khả năng khác được đề cập. Ví dụ: có cách nào để "lập chỉ mục" một số nội dung (ví dụ: sử dụng Map trường hợp) để bạn không phải sử dụng vòng lặp brute-force không?

2

Xem Branching Statements Java Tutorial để biết cách dễ nhất, sử dụng nhãn. Bạn có thể gắn nhãn bất kỳ hoặc tất cả các vòng lặp, sau đó sử dụng break hoặc continue cùng với các nhãn đó.

Thay thế cho việc sử dụng nhãn là sử dụng return thay thế. Chỉ cần cấu trúc lại mã của bạn thành một cuộc gọi phương thức để bỏ qua nhu cầu sử dụng nhãn.

2

Ví dụ của bạn khá chung chung nên thật khó để nói điều gì đang xảy ra nhưng tôi nhận được mã mùi mạnh mẽ từ mã bạn cung cấp mà tôi buộc phải nghĩ rằng phải có một cách khác để làm điều hoàn toàn , rất có thể thông qua việc tái cấu trúc cấu trúc dữ liệu thực tế thành một cái gì đó có ý nghĩa hơn.

Loại danh sách objects là gì? Điều gì khác (rất có thể quan trọng) dữ liệu chứa? Nếu nó không phải là quá nhiều rắc rối, tôi sẽ đánh giá cao nếu bạn cung cấp mã có liên quan hơn kể từ khi các nhà tái cấu trúc trong tôi là nhận được tất cả ham chơi chỉ nhìn thấy đống đống.

Các vấn đề liên quan