Có hai vấn đề ở đây:
Vấn đề đầu tiên là, thêm vào một Collection
sau khi một Iterator
được trả về. Như đã đề cập, không có hành vi xác định khi cơ bản Collection
được sửa đổi, như đã lưu ý trong tài liệu cho Iterator.remove
:
... Hành vi của một trình lặp là không xác định nếu tập hợp cơ bản được sửa đổi trong khi quá trình lặp đang diễn ra theo bất kỳ cách nào khác ngoài việc gọi phương thức này.
Vấn đề thứ hai là, ngay cả khi một phần tử Iterator
có thể được lấy, và sau đó quay trở lại cùng một phần tử Iterator
lúc đó, không có gì đảm bảo về thứ tự của lần lặp, như đã lưu ý trong Collection.iterator
tài liệu phương pháp:
... Không có đảm bảo nào liên quan đến thứ tự mà các phần tử được trả về (trừ khi tập hợp này là một thể hiện của một số lớp cung cấp một bảo đảm).
Ví dụ, giả sử chúng ta có danh sách [1, 2, 3, 4]
.
Giả sử nó 5
đã được thêm vào Iterator
lúc nào 3
, và bằng cách nào đó, chúng ta nhận được một Iterator
cái có thể tiếp tục lặp lại từ đó 4
. Tuy nhiên, không có người giám hộ nào 5
sẽ đến sau 4
. Thứ tự lặp có thể là [5, 1, 2, 3, 4]
- sau đó trình lặp sẽ vẫn bỏ sót phần tử 5
.
Vì không có gì đảm bảo cho hành vi, người ta không thể cho rằng mọi thứ sẽ xảy ra theo một cách nhất định.
Một cách thay thế có thể là có một phần riêng biệt Collection
mà các phần tử mới tạo có thể được thêm vào và sau đó lặp lại các phần tử đó:
Collection<String> list = Arrays.asList(new String[]{"Hello", "World!"});
Collection<String> additionalList = new ArrayList<String>();
for (String s : list) {
additionalList.add(s);
}
for (String s : additionalList) {
System.out.println(s);
}
Biên tập
Xây dựng trên câu trả lời của Avi , có thể xếp các phần tử mà chúng ta muốn lặp lại vào một hàng đợi và loại bỏ các phần tử trong khi hàng đợi có các phần tử. Điều này sẽ cho phép "lặp lại" các phần tử mới ngoài các phần tử ban đầu.
Hãy xem nó sẽ hoạt động như thế nào.
Về mặt khái niệm, nếu chúng ta có các phần tử sau trong hàng đợi:
[1, 2, 3, 4]
Và, khi chúng tôi xóa 1
, chúng tôi quyết định thêm 42
, hàng đợi sẽ như sau:
[2, 3, 4, 42]
Vì hàng đợi là cấu trúc dữ liệu FIFO (nhập trước, xuất trước), thứ tự này là điển hình. (Như đã lưu ý trong tài liệu về Queue
giao diện, đây không phải là điều cần thiết của a Queue
. Lấy trường hợp PriorityQueue
sắp xếp thứ tự các phần tử theo thứ tự tự nhiên của chúng, vì vậy đó không phải là FIFO.)
Sau đây là một ví dụ sử dụng LinkedList
(là a Queue
) để đi qua tất cả các phần tử cùng với các phần tử bổ sung được thêm vào trong quá trình dequeing. Tương tự như ví dụ trên, phần tử 42
được thêm vào khi phần tử 2
bị xóa:
Queue<Integer> queue = new LinkedList<Integer>();
queue.add(1);
queue.add(2);
queue.add(3);
queue.add(4);
while (!queue.isEmpty()) {
Integer i = queue.remove();
if (i == 2)
queue.add(42);
System.out.println(i);
}
Kết quả là như sau:
1
2
3
4
42
Như hy vọng, phần tử 42
được thêm vào khi chúng tôi nhấn đã 2
xuất hiện.