2009-11-03 38 views
32

Trong Eclipse, tôi thấy rằng các đối tượng ArrayList có trường modCount. Mục đích của nó là gì? (số lượng sửa đổi?)Java Modcount (ArrayList)

+2

'src.zip' là bạn của bạn. –

+0

xem mã tại đây http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/ArrayList.java#ArrayList.ListItr – roottraveller

Trả lời

28

Nó cho phép các bên trong danh sách biết liệu có sửa đổi cấu trúc nào có thể khiến hoạt động hiện tại đưa ra kết quả không chính xác.

Nếu bạn đã từng nhận được ConcurrentModificationException do sửa đổi danh sách (ví dụ: xóa mục) trong khi lặp lại nó, nội bộ của nó modCount là nội dung bị tắt khỏi trình lặp.

AbstractList docs cung cấp mô tả chi tiết tốt.

+0

Liên kết trong câu trả lời của bạn bị hỏng, đây là liên kết cố định -ttttps: //docs.oracle.com/javase/7/docs/api/java/util/AbstractList.html#modCount –

+0

Cảm ơn bạn đã cung cấp thông tin, nhưng có thể bạn xây dựng nhiều hơn trên Tài liệu, việc đoán Tài liệu luôn không hoàn chỉnh nếu không có ví dụ điển hình. Các tài liệu nói rằng "Sửa đổi cấu trúc là những thay đổi kích thước của danh sách, hoặc nói cách khác là làm thay đổi kích thước của danh sách, có thể mang lại kết quả không chính xác", nhưng điều này có thể gây ra trường hợp nào. đúng. –

15

Có. Nếu bạn đã từng có ý định mở rộng AbstractList, bạn phải viết mã của bạn để nó tuân thủ javadoc của modCount như trích dẫn dưới đây:

/** 
* The number of times this list has been <i>structurally modified</i>. 
* Structural modifications are those that change the size of the 
* list, or otherwise perturb it in such a fashion that iterations in 
* progress may yield incorrect results. 
* 
* <p>This field is used by the iterator and list iterator implementation 
* returned by the {@code iterator} and {@code listIterator} methods. 
* If the value of this field changes unexpectedly, the iterator (or list 
* iterator) will throw a {@code ConcurrentModificationException} in 
* response to the {@code next}, {@code remove}, {@code previous}, 
* {@code set} or {@code add} operations. This provides 
* <i>fail-fast</i> behavior, rather than non-deterministic behavior in 
* the face of concurrent modification during iteration. 
* 
* <p><b>Use of this field by subclasses is optional.</b> If a subclass 
* wishes to provide fail-fast iterators (and list iterators), then it 
* merely has to increment this field in its {@code add(int, E)} and 
* {@code remove(int)} methods (and any other methods that it overrides 
* that result in structural modifications to the list). A single call to 
* {@code add(int, E)} or {@code remove(int)} must add no more than 
* one to this field, or the iterators (and list iterators) will throw 
* bogus {@code ConcurrentModificationExceptions}. If an implementation 
* does not wish to provide fail-fast iterators, this field may be 
* ignored. 
*/ 

Lấy một cái nhìn vào mã nguồn thực tế JDK và đọc javadocs (trực tuyến hoặc trong code) giúp đỡ rất nhiều trong việc hiểu những gì đang xảy ra. Chúc may mắn.

Tôi sẽ thêm, bạn có thể thêm mã nguồn JDK vào Eclipse để mỗi F3 hoặc CTRL + nhấp vào bất kỳ điểm Java/điểm phương thức nào đến mã nguồn thực tế. Nếu bạn tải xuống JDK, bạn nên có src.zip trong thư mục cài đặt JDK. Bây giờ, trong trình đơn trên cùng của Eclipse, vào Window »Preferences» Java »JRE được cài đặt. Chọn JRE hiện tại và nhấp vào Chỉnh sửa. Chọn tệp rt.jar, nhấp vào Tệp đính kèm nguồn, nhấp vào Tệp bên ngoài, điều hướng đến thư mục JDK, chọn tệp src.zip và thêm tệp đó. Bây giờ mã nguồn của API Java SE có sẵn trong Eclipse. Mã nguồn JDK cung cấp thông tin chi tiết. Chúc mừng mã hóa :)

+1

Tôi đã thêm một số giải thích cách tích hợp mã nguồn Java SE vào Eclipse. Câu hỏi ban đầu khiến tôi nghĩ rằng anh ta chưa làm điều đó trong khi đó là một PHẢI cho mọi nhà phát triển Java. – BalusC

1

Từ Java API cho trường đếm mod:

Số lần danh sách này đã được sửa đổi về mặt cấu trúc. Sửa đổi cấu trúc là những thay đổi kích thước của danh sách hoặc nói cách khác là làm xáo trộn nó theo cách như vậy mà các lần lặp lại có thể mang lại kết quả không chính xác.

4

Đó là số lần cơ cấu (size) của bộ sưu tập thay đổi

0

From the 1.4 javadoc on AbstractList:

bảo vệ thoáng int modCount

Số lần danh sách này đã được cấu trúc đã sửa đổi. Cấu trúc sửa đổi là những thay đổi kích thước của danh sách, hoặc nếu không làm phiền nó theo cách như vậy mà lặp lại trong quá trình có thể mang lại kết quả không chính xác .

Trường dữ liệu này được sử dụng bởi trình vòng lặp và thực hiện trình vòng lặp danh sách trả về bằng phương thức vòng lặp và phương thức listIterator . Nếu giá trị của trường này là thay đổi bất ngờ, trình lặp vòng lặp (hoặc trình vòng lặp danh sách) sẽ ném ConcurrentModificationException trong phản hồi tới lần tiếp theo, xóa, trước đó, đặt hoặc thêm hoạt động. Điều này cung cấp hành vi không nhanh, thay vì hơn hành vi không xác định trong khuôn mặt sửa đổi đồng thời trong thời gian lặp lại.

Việc sử dụng trường này theo lớp con là tùy chọn.

2

protected transient int modCount = 0;
là thuộc tính được khai báo tại public abstract class AbstractList,
để xác định tổng số sửa đổi cấu trúc được thực hiện trong bộ sưu tập này.

Có nghĩa là nếu có thêm/xóa sẽ có tăng trong bộ đếm này cho cả hai thao tác. Do đó, bộ đếm này luôn được tăng lên cho bất kỳ sửa đổi nào. Vì vậy, không hữu ích cho tính toán kích thước.

Điều này sẽ hữu ích khi ném ConcurrentModificationException.
ConcurrentModificationException sẽ được ném trong khi lặp lại bộ sưu tập theo một chuỗi và có một sửa đổi trong bộ sưu tập theo một chuỗi khác. Điều này đạt được như bất cứ khi nào đối tượng iterator được tạo modCount sẽ được đặt thành expectedCount, và mỗi chuyển hướng iterator expectedCount sẽ được so sánh với modCount để ném ConcurrentModificationException khi có thay đổi.

private class Itr implements Iterator<E> { 
    ... 
    ... 
    /** 
    * The modCount value that the iterator believes that the backing 
    * List should have. If this expectation is violated, the iterator 
    * has detected concurrent modification. 
    */ 
    int expectedModCount = modCount; 

    public E next() { 
     checkForComodification(); 
    ... 
    ... 
    } 

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

} 

size() api sẽ không phù hợp ở đây; kể từ khi có hai hoạt động (thêm và loại bỏ) xảy ra trước khi tiếp theo() được gọi là kích thước vẫn sẽ hiển thị cùng một giá trị; do đó không thể phát hiện sửa đổi đã xảy ra trên bộ sưu tập này bằng cách sử dụng size() api trong khi lặp lại. Do đó, chúng tôi cần sửa đổi_increment_counter làmodCount.

+0

tuyệt vời. xem toàn bộ mã tại đây: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/ArrayList.java#ArrayList.ListItr – roottraveller

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