thể trùng lặp:
Why is Java's Iterator not an Iterable?Tại sao Java không cho phép foreach trên các trình vòng lặp (chỉ trên các vòng lặp)?Idiomatic way to use for-each loop given an iterator?
Can we use for-each loop for iterating the objects of Iterator type?
Các foreach vòng lặp là như xa như tôi biết đường cú pháp bổ sung trong Java 5. Vì vậy,
Iterable<O> iterable;
for(O o : iterable) {
// Do something
}
về cơ bản sẽ tạo ra bytecode giống như
Iterable<O> iterable;
for(Iterator<O> iter = iterable.iterator(); iter.hasNext(); /* NOOP */) {
O o = iter.next();
// Do something
}
Tuy nhiên, nếu tôi không có một iterable ở nơi đầu tiên, nhưng chỉ một iterator (nói, bởi vì một lớp học cung cấp hai vòng lặp khác nhau), tôi có thể không sử dụng vòng lặp foreach đường cú pháp. Rõ ràng tôi vẫn có thể thực hiện lặp lại kiểu cũ đơn giản. Tuy nhiên, tôi thực sự muốn làm:
Iterator<O> iter;
for(O o : iter /* Iterator<O>, not Iterable<O>! */) {
// Do something
}
Và dĩ nhiên tôi có thể làm một giả Iterable
:
class Adapter<O> implements Iterable<O> {
Iterator<O> iter;
public Adapter(Iterator<O> iter) {
this.iter = iter;
}
@Override
public Iterator<O> iterator() {
return iter;
}
}
(Mà trên thực tế là một sự lạm dụng xấu xí của API Iterable, vì nó có thể ! chỉ được lặp một lần)
Nếu nó được thiết kế xung quanh Iterator
thay vì iterable, người ta có thể làm một số điều thú vị:
for(O o : iterable.iterator()) {} // Iterate over Iterable and Collections
for(O o : list.backwardsIterator()) {} // Or backwards
Iterator<O> iter;
for(O o : iter) {
if (o.something()) { iter.remove(); }
if (o.something()) { break; }
}
for(O : iter) { } // Do something with the remaining elements only.
Có ai biết lý do tại sao ngôn ngữ được thiết kế theo cách này? Để tránh sự mơ hồ nếu một lớp học sẽ triển khai cả hai Iterator
và Iterable
? Để tránh các lỗi lập trình giả định rằng "for (O o: iter)" sẽ xử lý tất cả các phần tử hai lần (và quên để có được một iterator mới)? Hoặc là có một số lý do khác cho việc này?
Hoặc có một số mẹo ngôn ngữ tôi chỉ không biết?
Hoặc [this one] (http://stackoverflow.com/questions/2162917/can-we-use-for-each-loop-for-iterating-the-objects-of-iterator-type). –
Cả hai bản sao gần giống nhau, nhưng không hoàn toàn giống nhau. Iterator không nên lặp lại, bởi vì bạn chỉ có thể lặp lại một lần (không "khởi động lại"). Và tôi biết rằng bạn không thể sử dụng foreach trên các trình vòng lặp (trừ khi bạn sử dụng bộ điều hợp mà tôi phác thảo), nhưng tôi đang cố gắng hiểu tại sao Java được thiết kế theo cách này. –
Meh; Tôi có xu hướng không đồng ý. Câu trả lời được đưa ra trong 1.5 tài liệu nói rằng các nhà thiết kế đã chọn cách này để xử lý các trường hợp sử dụng phổ biến nhất. Đôi khi câu trả lời * là * "chỉ vì". –