2009-11-03 21 views
32

En Eclipse, veo que los objetos ArrayList tienen un campo modCount. ¿Cual es su propósito? (¿número de modificaciones?)Java Modcount (ArrayList)

+2

'src.zip' es tu amigo. –

+0

ver el código aquí http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/ArrayList.java#ArrayList.ListItr – roottraveller

Respuesta

28

Permite que las partes internas de la lista sepan si se ha realizado alguna modificación estructural que pueda ocasionar que la operación actual dé resultados incorrectos.

Si alguna vez ha obtenido ConcurrentModificationException debido a la modificación de una lista (por ejemplo, eliminar un elemento) mientras la itera, su interno modCount fue lo que alertó al iterador.

El AbstractList docs da una buena descripción detallada.

+0

El enlace en su respuesta está roto, este es el fijo -https: //docs.oracle.com/javase/7/docs/api/java/util/AbstractList.html#modCount –

+0

Gracias por la información, pero puede elaboras más sobre los Documentos, adivinando que los Documentos siempre están incompletos sin un buen ejemplo. El documento dice: "Las modificaciones estructurales son aquellas que cambian el tamaño de la lista, o la perturban de tal manera que las iteraciones en curso pueden arrojar resultados incorrectos", pero ¿qué es posible con esta perturbación? Explicar cualquier caso para obtenerla derecho. –

15

Sí. Si alguna vez tiene la intención de ampliar AbstractList, usted tiene que escribir el código para que se adhiera javadoc del modCount como se cita a continuación:

/** 
* 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. 
*/ 

Echando un vistazo al código real fuente de JDK y la lectura de los javadocs (ya sea en línea o en código) ayuda mucho a entender lo que está pasando. Buena suerte.

Yo agregaría, puede agregar código fuente JDK a Eclipse para que cada F3 o CTRL + clic en cualquier clase/método de Java SE apunte al código fuente real. Si descarga el JDK, debe tener src.zip en la carpeta de instalación de JDK. Ahora, en el menú superior de Eclipse, vaya a Ventana »Preferencias» Java »JRE instalados. Seleccione el JRE actual y haga clic en Editar. Seleccione el archivo rt.jar, haga clic en Archivos adjuntos de origen, haga clic en Archivo externo, navegue a la carpeta JDK, seleccione el archivo src.zip y añádalo. Ahora el código fuente de la API Java SE está disponible en Eclipse. El código fuente de JDK da un lote de estadísticas. Feliz de codificación :)

+1

He añadido algunas explicaciones cómo integrar el código fuente de Java SE en Eclipse. La pregunta original me hizo pensar que aún no lo hizo mientras que es IMPRESCINDIBLE para cada desarrollador de Java. – BalusC

1

Desde el Java API para el campo de recuento mod:

El número de veces que esta lista se ha modificado estructuralmente. Las modificaciones estructurales son aquellas que cambian el tamaño de la lista o la perturban de tal manera que las iteraciones en progreso pueden arrojar resultados incorrectos.

4

Es el número de veces que la estructura (tamaño) de la colección cambia

0

From the 1.4 javadoc on AbstractList:

transitoria protegida int modCount

El número de veces que esta lista ha sido estructuralmente modificado. Las modificaciones estructurales son aquellas que cambian el tamaño de la lista o, de lo contrario, lo perturban de tal manera que las iteraciones en progreso pueden arrojar resultados incorrectos.

Este campo es utilizado por el iterador y implementación de la lista iterador devuelto por el iterador y métodos listIterator . Si el valor de este campo cambia inesperadamente, el iterador (o el iterador de lista ) arrojará una ConcurrentModificationException en la respuesta a la siguiente, elimine, anterior, configure o agregue operaciones. Este proporciona un comportamiento a prueba de fallos, más bien que el comportamiento no determinista en la cara de la modificación concurrente durante la iteración .

El uso de este campo por subclases es opcional.

2

protected transient int modCount = 0;
es la propiedad declarada en public abstract class AbstractList,
para identificar el número total de modificación estructural realizado en esta colección.

Significa que si hay un add/remove habrá un incremento en este contador para ambas operaciones. Por lo tanto, este contador siempre se incrementa para cualquier modificación. Por lo tanto, no es útil para el cálculo de tamaño.

Esto será útil para arrojar ConcurrentModificationException.
ConcurrentModificationException se lanzará al iterar la colección por un hilo y hay una modificación en la colección por otro hilo. Esto se logra como cuando se crea un objeto iterador. ModCount se configura en expectedCount, y cada navegación del iterador. ExpectedCount se compara con modCount para arrojar ConcurrentModificationException cuando hay un cambio.

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 no se adaptará aquí; ya que si hay dos operaciones (agregar y eliminar) pasadas antes del próximo(), el tamaño fijo llamado mostrará el mismo valor; por lo tanto, no puede detectar la modificación ocurrida en esta colección usando size() api while iteration. Por lo tanto, necesitamos modification_increment_counter que esmodCount.

+0

excelente. vea el código completo aquí: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/ArrayList.java#ArrayList.ListItr – roottraveller