2013-10-08 20 views
6

Có những câu hỏi tương tự nhưng không chính xác những gì tôi muốn hỏi. Tôi muốn hỏi cách Iterator kiểm tra sửa đổi.không thực hiện lặp lại nhanh chóng

This link nói rằng việc triển khai của nó hiện diện trong lớp AbstractList trong đó một biến mod int được định nghĩa cung cấp số lần kích thước danh sách đã được thay đổi. Giá trị này được sử dụng trong mỗi lần gọi() tiếp theo để kiểm tra bất kỳ sửa đổi nào trong hàm checkForComodification().

Nhưng tôi thực sự không thể hiểu được. Nếu giá trị được kiểm tra chỉ sau mỗi cuộc gọi tiếp theo thì nếu tôi thực hiện lệnh xóa, tiếp theo là thêm vào cùng một cuộc gọi, kích thước sẽ không thay đổi và modCount cũng không được thay đổi. Nhưng việc loại bỏ và thêm vào cùng một vòng lặp lặp lại cũng ném ngoại lệ.

Trả lời

8

Nếu bạn xem mã để triển khai Collection, hãy chọn ArrayList; chúng ta có một biến modCount khai báo trong AbstractList:

protected transient int modCount = 0; 

Và sau đó trong mỗi và mọi phương pháp sửa đổi (ví dụ remove) cho ArrayList chúng tôi có

public E remove(int index) { 
    rangeCheck(index); 

    modCount++; 
    //.... 

Vì vậy, các modCount là duy nhất từng tăng lên ; nó là không bao giờ bị giảm.

Trong Iterator sau đó chúng ta có:

final void checkForComodification() { 
    if (modCount != expectedModCount) 
     throw new ConcurrentModificationException(); 
} 

đâu expectedModCount là một bản chụp của modCount chụp tại Iterator sáng tạo.

Vì vậy, nếu có bất kỳ sửa đổi để các tiềm ẩn List trong khi cùng một ví dụ của một Iterator được sử dụng sau đó một ConcurrentModificationException sẽ được ném ra.

Tôi cho rằng có trường hợp góc nếu bạn thực hiện đủ sửa đổi thì int sẽ tràn và trở về giá trị ban đầu của nó một lần nữa - đây sẽ là số lượng hoặc sửa đổi khá lớn; 2 chính xác.

6

modCount luôn tăng khi danh sách được sửa đổi (do đó mod đếm) vì vậy nó cũng sẽ tăng khi có loại bỏ. Vì vậy, nó sẽ tăng trên cả hai loại bỏ và thêm cuộc gọi.

Như Boris the Spider nói có phải là trường hợp góc modCount tràn, bạn có thể nhìn thấy nó bằng cách thực hiện:

List<Integer> nums = new ArrayList<>(); 
for(int i = 0; i < 10; i++) nums.add(i); 
for(int n : nums) { 
    System.out.println(n); 
    for(int i = -1; i < Integer.MAX_VALUE; i++) { 
     nums.add(i); 
     nums.remove(nums.size() - 1); 
    } 
} 

nào sẽ (chậm) in 0 đến 9 mà không ném bất kỳ ngoại lệ.

+0

+1, có. Nhưng bạn không cần phải giả định, [mã có sẵn] (http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7-b147/java/util/AbstractList. java # AbstractList.0modCount). – yshavit

+0

@yshavit Tôi đã viết nó trước khi kiểm tra mã;) – Alowaniak

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