Leí una oración antes, y fue muy bueno. Alguien preguntó cuál es el uso del código fuente de lectura. Aprenda las ideas de diseño de otros para implementar una determinada función y mejorar su nivel de programación.
Sí, todos implementan una función. Diferentes personas tienen diferentes ideas de diseño. Algunas personas usan 10,000 líneas de código, y algunas personas usan 5,000 líneas. Algunas personas necesitan ejecutar el código durante docenas de segundos, mientras que otras solo necesitan unos segundos. . Vamos al tema a continuación.
Contenido principal de este artículo:
・Un comentario detallado sobre la implementación de ArrayList, basado en JDK 1.8.
・La parte sublista de Iterator no se ha explicado en detalle y se colocará en otras interpretaciones del código fuente. Aquí nos centramos en la implementación de ArrayList en sí.
・No se utilizan anotaciones estándar, y la sangría del código se ajusta adecuadamente para una fácil introducción
import java.util.abstractList; import java.util.arrays; import java.util.bitset; import java.util.collection; import java.util.comparator; import java.util.concurrentModificationException; import java.util.iterator; import java.util.list; import java.utilator; import java.util.iterator; import java.util.list; import java.utiler; java.util.nosuchelementException; import java.util.objects; import java.util.randomAccess; import java.util.spliterator; import java.util.function.consumer; import java.util.function.predicate; import java.util.function.unararioperator;///////** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ANCHULE: ** ANIL Implementación de la interfaz de la lista que se puede cambiar el tamaño. Implemente todas las operaciones de lista opcionales y permiten que todos los elementos, incluido NULL, sean repetibles. * Además de la interfaz de la lista, esta clase proporciona una forma de manipular el tamaño de la matriz para almacenar el tamaño de la matriz en la lista. * * Complejidad del tiempo: * Las llamadas al tamaño de los métodos, isEmpty, get, set, iterator y listIterator son tiempo constante. * La complejidad del tiempo de agregar y eliminar es o (n). Todas las demás operaciones son complejidad del tiempo lineal. * * Capacidad: * Cada ArrayList tiene capacidad, y el tamaño de la capacidad es al menos la longitud del elemento de lista, y la inicialización predeterminada es 10. * La capacidad se puede aumentar automáticamente. * Si sabe de antemano que hay muchos elementos en la matriz, puede aumentar la capacidad de antemano llamando al método EnsureCapacity () antes de agregar elementos para reducir la sobrecarga del crecimiento automático de la capacidad en el período posterior. * Esta capacidad también puede ser inicializada por un constructor con capacidad inicial. * * El hilo no es seguro: * ArrayList no es seguro. * Si es necesario aplicar a múltiples lecturas, la sincronización debe hacerse externamente * * ModCount: * Definido en AbstractList: protegido transitorio int modcount = 0; * Número de veces esta lista se ha modificado estructuralmente. La modificación estructural se refiere a cambiar el tamaño de la lista, o alterar la lista, de modo que la iteración continua produce resultados incorrectos. * Este campo es utilizado por las implementaciones de iterador y iterador de la lista devueltas por los métodos de iterador y listerador. * Si el valor en este campo se cambia accidentalmente, el iterador (o iterador de la lista) lanzará una medición de modificación concurrente en respuesta a las operaciones Siguiente, Eliminar, Establecer o Agregar o Agregar. * Cuando se enfrenta a modificaciones concurrentes durante las iteraciones, proporciona un comportamiento fallido rápido en lugar del comportamiento no determinista. * Si la subclase usa este campo es opcional. * Si la subclase desea proporcionar un iterador de falla rápida (y la lista de la lista), simplemente agrega este campo a sus métodos ADD (int, e) y eliminación (int) (y cualquier otro método que anule, lo que resulta en modificaciones en la estructura de la lista). * El número de llamadas individuales para agregar (int, e) o eliminar (int) no debe exceder 1 a este campo; de lo contrario, el iterador (y la lista iterator) lanzará las cepciones falsas de modificación concurrente. * Si una implementación no quiere proporcionar un iterador de falla rápida, este campo se puede ignorar. * * Transitorio: * Por defecto, se persistirán todas las variables miembros de un objeto. En algunos casos, si desea evitar persistir en algunas variables de miembros de un objeto, puede usar la palabra clave transitoria para etiquetarlas, que también es una palabra reservada en java (jdk 1.8) */public class ArrayList <E> extiende la lista abstracta <E> Lista de implementos de implementación <E>, RandomAccess, clonable clonable, java.iO.serializable {privado static sertentsionversionsionsionsionsionsionsionsionsion. 8683452581122892189l; // Capacidad inicial predeterminada estática privada final int default_capacity = 10; // se usa para compartir instancias de matriz vacías con instancias vacías. objeto final estático privado [] vacía_elementData = {}; // Matriz vacío predeterminado Objeto final estático privado [] defaultCapacity_empty_elementData = {}; // Para la derecha, la matriz de elementos, los permisos de acceso al paquete se almacenan objeto transitorio [] elementData; // Tamaño, Java inicializará int a 0 al crear un objeto privado intize int; // Establezca el constructor de la capacidad de inicialización con el número especificado, y el número negativo lanzará una excepción pública ArrayList (int InitialCapacity) {if (InicialCapacity> 0) {this.ElementData = new Object [inicialCapacity]; } else if (inicialCapacity == 0) {this.elementData = vacía_elementData; } else {tirar nueva ilegalArgumentException ("Capacidad ilegal:"+InicialCapacity); }} // constructor predeterminado, use la matriz de control para inicializar public arrayList () {this.elementData = defaultCapacity_Empty_elementData; } // Construye una lista que contenga elementos en la colección en el orden del regreso de la colección de la colección pública arrayList (colección <? Extiende e> c) {elementData = c.toarray (); if ((size = elementData.length)! = 0) {// c.toarray puede (error) no return Object [] (ver Java Bug Number 6260652) if (elementData.getClass ()! = Object []. Class) ElementData = Arrays.CopyOf (ElementData, Size, Object []. Class); } else {// use una matriz vacía this.elementData = vacía_elementData; }} // porque la capacidad a menudo es mayor que el número real de elementos. Cuando la memoria está ajustada, puede llamar a este método para eliminar la ubicación reservada y ajustar la capacidad al número real de elementos. // Si está seguro de que no se agregarán elementos, también puede llamar a este método para ahorrar espacios public void Trimtosize () {ModCount ++; if (size <elementData.length) {elementData = (size == 0)? Vacía_elementData: arrays.copyOf (elementData, size); }} // Establezca capacidad de matriz con parámetros especificados public void setureCapacity (int mincapacity) {// Si la matriz está vacía, prefectar 0, de lo contrario, vaya al valor predeterminado (10) int minexpand = (elementData! = Defaultcapacity_empty_elementData)? 0: default_capacity; // Si el parámetro es mayor que la capacidad preestablecida, use este parámetro para establecer aún más la capacidad de matriz if (mincapacity> minexpand) {asegurarxplicitcapacity (mincapacity); }} // Al agregar elementos, asegúrese de que la capacidad de matriz private void asurecapacityInternal (int mincapacity) {// use el valor predeterminado y el parámetro más grande como el valor preestablecido de capacidad if (elementData == Defaultcapacity_empty_elementData) {mincapacity = math.max (predeterminado_capacidad, mincapacity); } asegurar EXUSEXPICITCAPACCID (minCapacity); } // Si el parámetro es mayor que la capacidad de la matriz, aumente la capacidad de matriz privada void aseXplicitCapacity (int mincapacity) {modCount ++; if (mincapacity - elementData.length> 0) Grow (mincapacity); } // La capacidad máxima de la matriz puede causar desbordamiento de memoria (Límite de memoria VM) Private estático final int max_array_size = Integer.max_value - 8; // Aumentar la capacidad para garantizar que pueda contener al menos el número de elementos especificados por el parámetro privado void grow (int mincapacity) {int OldCapacity = elementData.length; // aumentar la capacidad preestablecida a mitad int newcapacity = OldCapacity + (OldCapacity >> 1); // Tome el valor mayor del parámetro if (newCapacity - mincapacity <0) // es decir, newCapacity <mincapacity newCapacity = mincapacity; // Si el valor preestablecido es mayor que el máximo predeterminado, verifique si se desborda si (newCapacity - max_array_size> 0) newCapacity = HugeCapacity (minCapacity); elementData = arrays.copyOf (elementData, newCapacity); } // Verifique si se desborda. Si no hay desbordamiento, devuelva el valor de entero máximo (el int en Java es 4 bytes, por lo que el máximo es 0x7ffffff) o el valor máximo predeterminado privado static static int hugeCapacity (int mincapacity) {if (mincapacity <0) // Overflow throw NewOfMemoryerRorRor ();; return (mincapacity> max_array_size)? Integer.max_value: max_array_size; } // devuelve el tamaño de matriz public int size () {return size; } // ¿Está vacío público boolean isEtimty () {return size == 0; } // Si contiene un número, return bool public boolean contiene (objeto o) {return indexOf (o)> = 0; } // Devuelve un valor a la primera aparición de la matriz, y se juzgará de diferentes maneras en función de si es nulo. Si no existe, devuelve -1. La complejidad del tiempo es o (n) public int indexOf (objeto o) {if (o == null) {for (int i = 0; i <size; i ++) if (elementData [i] == null) return i; } else {for (int i = 0; i <size; i ++) if (o.equals (elementData [i])) return i; } return -1; } // devuelve un valor en la última vez cuando aparece en la matriz. Si no existe, devuelve -1. La complejidad del tiempo es o (n) public int LastIndexof (objeto o) {if (o == null) {for (int i = size-1; i> = 0; i--) if (elementData [i] == null) return i; } else {for (int i = size-1; i> = 0; i--) if (o.equals (elementData [i])) return i; } return -1; } // Devuelve la copia, el elemento en sí no se ha copiado, y se lanzará una excepción cuando la matriz del proceso de copia cambie el objeto público clone () {try {arrayList <?> v = (arrayList <?>) super.clone (); V.ElementData = arrays.copyOf (elementData, tamaño); v.modcount = 0; regreso v; } Catch (clonenotsupportedException e) {tirar nueva internalSor (e); }} // Convertir a una matriz de objetos, use el objeto público de método arrays.copyOf () [] toArray () {return arrays.copyOf (elementData, size); } // devuelve una matriz, use el tiempo de ejecución para determinar el tipo, y la matriz contiene todos los elementos en esta lista (desde el primer elemento) // La capacidad de matriz devuelta está determinada por los parámetros y el valor más grande en esta matriz @suppressWarnings ("no verificado") público <t> t [] toArray (t [] a) {if (a.slengggthing (size (size) de regreso (tize) Arrays.copyOf (elementData, size, a.getClass ()); System.ArrayCopy (ElementData, 0, a, 0, tamaño); if (a.length> size) a [size] = null; regresar a; } // Devuelve el valor de la posición especificada, porque es una matriz, es particularmente rápido @supresswarnings ("sin control") e elementSdata (int index) {return (e) elementdata [index]; } // devuelve el valor de la posición especificada, pero verifique si el número de posiciones excede la longitud de matriz public e get (int index) {rangeCheck (index); return ElementData (índice); } // Establezca la posición especificada en un nuevo valor y devuelva el valor anterior, verifique si esta posición excede la longitud de matriz public e set (int index, e element) {rangeCheck (index); E OldValue = elementData (índice); elementData [index] = elemento; devolver OldValue; } // Agregar un valor primero garantiza la capacidad de publicidad public boolean (e e) {EnsurecapacityInternal (tamaño + 1); elementData [size ++] = e; devolver verdadero; } // Agregue un valor en la posición especificada y verifique la posición y la capacidad adicionales de publicidad Void add (int index, e elemento) {rangeCheckforAdd (índice); EnsurecapacityInternal (tamaño + 1); // Public static void arrayCopy (objeto src, int srcpos, object dest, int Destpos, int longitud) // src: fuente matriz; SRCPOS: la posición inicial de la matriz de origen que se copiará; Dest: matriz de destino; Destpos: la posición inicial de la matriz de destino; Longitud: Copiar longitud de longitud. elementData [index] = elemento; tamaño ++; } // Eliminar el valor de la posición especificada, verifique la posición agregada y devuelva el valor anterior public e remove (int index) {rangeCheck (index); ModCount ++; E OldValue = elementData (índice); int numMoved = tamaño - índice - 1; if (numMoved> 0) System.ArrayCopy (ElementData, índice+1, elementData, index, numMoved); elementData [-size] = null; // Fácil de reciclar el período de recolección de basura retorno OldValue; } // Elimine la ubicación donde el elemento especificado aparece primero en público boolean remove (objeto o) {if (o == null) {for (int index = 0; index <size; index ++) if (elementData [index] == null) {fastremove (index); devolver verdadero; }} else {for (int index = 0; index <size; index ++) if (o.equals (elementData [index])) {fastremove (index); devolver verdadero; }} return false; } // Elimine rápidamente el valor en la posición especificada. La razón por la que se llama RÁPIDO debería ser que no hay necesidad de verificar y devolver el valor, porque solo privado Fastremove (int index) {ModCount ++; int numMoved = tamaño - índice - 1; if (numMoved> 0) System.ArrayCopy (ElementData, índice+1, elementData, index, numMoved); elementData [-size] = null; // claro para dejar que GC haga su trabajo} // Borrar la matriz y establecer cada valor en nulo para facilitar la recolección de basura (a diferencia del reinicio, el tamaño predeterminado de la matriz no se restablecerá si cambia) public void clear () {modcount ++; para (int i = 0; i <size; i ++) elementData [i] = null; tamaño = 0; } // Agregue un elemento de una colección al final, si la colección que se agregará está vacía, devuelve falso público booleano addall (colección <? Extiende e> c) {objeto [] a = c.toarray (); int numnew = A.Length; EnsurecapacityInternal (tamaño + numnew); System.ArrayCopy (A, 0, ElementData, tamaño, numnew); tamaño += numnew; devuelve numnew! = 0; } // La función es la misma que la anterior, agregue public boolean addall (int index, colección <? Extiende e> c) {rangecheckforadd (index); Objeto [] a = c.toarray (); // La matriz que se agregará int numnew = a.length; // la longitud de la matriz a agregar Ensurecapacidad Interna (tamaño + numnew); // Asegurar la capacidad int numMoved = size - índice; // La longitud que no se moverá (la parte anterior) if (numMoved> 0) // Si no es necesario moverla, copiarla por sí misma y mover la parte posterior de la matriz a la posición correcta. System.ArrayCopy (A, 0, ElementData, índice, numnew); // Agregue una nueva matriz al medio del tamaño de matriz original cambiado += numnew; devuelve numnew! = 0; } // Eliminar el elemento de rango especificado. Los parámetros son las posiciones de inicio y finalización de removido vacío protegido (int fromIndex, int toIndex) {modcount ++; int numMoved = size - toindex; // La longitud retenida por la última sección System.ArrayCopy (elementData, ToIndex, ElementData, FromIdex, NumMoved); int newsize = size - (toindex -fromindex); para (int i = newsize; i <size; i ++) {elementData [i] = null; } size = Newsize; } // verifique si el número excede la longitud de la matriz al agregar elementos void privado rangecheck (int index) {if (index> = size) tirar nueva indexOutofboundsexception (outOfBoundSMSG (index)); } // verifique si el vacío privado rangecheckforadd (int index) {if (index> size || índice <0) tire nuevo indexOutOfBoundsexception (outOfBoundSMSG (index)); } // Detalles de la cadena privada de excepción lanzada fuera deboundsmsg (int index)) {return "índice:"+index+", tamaño:"+tamaño; } // Eliminar el elemento de la colección especificada pública boolean removeall (colección <?> C) {objetos.requirenonnull (c); // verifique si el parámetro es nulo de retorno batchremove (c, falso); } // Conservar solo los elementos de la colección especificada pública Boolean Retrainall (colección <?> C) {Objects.requirenonnull (c); return batchremove (c, verdadero); }/** * Interpretación del código fuente por http://anxpp.com/ * @param completo Cuando es verdadero, el valor del elemento en la colección especificada se conserva de la matriz, y cuando falsa, el valor del elemento en la colección especificada se elimina de la matriz. * @return Los elementos duplicados en la matriz se eliminarán (en lugar de simplemente eliminar una o varias veces), y cualquier operación de deleción devolverá verdadero */ privado boolean batchremove (colección <?> c, complemento booleano) {objeto final [] elementData = this.EmementData; int r = 0, w = 0; booleano modificado = falso; Pruebe {// Transweep a través de la matriz y verifique si esta colección contiene el valor correspondiente, mueva el valor que se retendrá al frente de la matriz, y el último valor de W es el número de elementos que se conservarán // Punto simple: si se conserva, mueva el mismo elemento a la sección anterior; Si se elimina, mueva diferentes elementos a la sección anterior para (; r <size; r ++) if (c.contains (elementData [r]) == complement) elementData [w ++] = elementData [r]; } Finalmente {// Asegúrese de que la parte antes de que se lance la excepción pueda completar la operación esperada, mientras que la parte que no se ha atravesado se conectará a la parte posterior // r! = tamaño significa que puede ocurrir un error: c.contains (elementData [r]) lanza una excepción si (r! = size) {system.arraycopy (ElementData, R, ElementData, W, Size - R); w += tamaño - r; } // Si w == tamaño: significa que todos los elementos se conservan, por lo que no se produce operación de eliminación, por lo que se devolverá falso; De lo contrario, verdadero y la matriz // cuando se devuelve el tamaño w! =, incluso si el bloque de try lanza una excepción, la operación antes de que se lance la excepción, porque W siempre es la longitud de la parte anterior a ser retenida, y la matriz no estará fuera de servicio porque (w! = tamaño) {para (int i = w; i <tamaño; i ++) elementdata [i] = null; ModCount += tamaño - W; // El número de veces cambiado de tamaño = W; // El nuevo tamaño es el número de elementos conservados modificados = true; }} return modificado; } // Guardar el estado de la instancia de la matriz en una secuencia (es decir, se es serializada). La matriz del proceso de escritura se cambia y se lanzará una excepción privada void writeObject (java.io.objectututputstream s) lanza java.io.ioException {int esperadomodcount = modcount; S.DefaultWriteObject (); // Ejecutar el proceso de deserialización/serialización predeterminado. Escriba campos no estatales y no transitivos de la clase actual a esta transmisión // Escribir a size s.writeint (tamaño); // Escribe todos los elementos para (int i = 0; i <size; i ++) {s.writeObject (elementData [i]); } if (modCount! = esperadoModCount) {lanzar nueva concurrenteModificationException (); }} // Lo anterior está escrito, esto se lee. Private void ReadObject (java.io.objectInputStream s) lanza java.io.ioException, classnotFoundException {elementData = vacía_elementData; // realizar el proceso de serialización/deserialización predeterminado S.DefaultreadObject (); // Leer en la longitud de la matriz s.ReadInt (); if (size> 0) {EnsureCapacityInternal (tamaño); Objeto [] a = elementData; // Leer en todos los elementos para (int i = 0; i <size; i ++) {a [i] = s.readObject (); }}}} // return listIterator, la posición inicial es el parámetro especificado Public listIterator <E> listIterator (int index) {if (index <0 || índice> tamaño) tirar nuevo indexOtoFBoundSeCception ("index:"+index); devolver nuevo listitr (índice); } // return listIterator, la posición inicial es 0 Public listIterator <E> listIterator () {return new Listitr (0); } // return ordinary iterator public Iterator <E> iterator () {return new Itr (); } // El iterador general implementa la clase privada ITR implementa Iterator <E> {int cursor; // El cursor, el índice del siguiente elemento, la inicialización predeterminada es 0 int Latret = -1; // La posición del último elemento de acceso es int se esperaba ModCount = modCount; // El proceso de iteración no ejecuta la matriz modificada, de lo contrario se lanzará una excepción // ¿Hay otro booleano público Hasnext () {return cursor! = Size; } // El siguiente elemento @suppleswarnings ("no verificado") public e next () {checkforcomodification (); // verifique si la matriz se modifica int i = cursor; if (i> = size) tire nuevo nosuchelementException (); Objeto [] elementData = ArrayList.This.ElementData; if (i> = elementData.length) tire nuevo concurrentModificationException (); cursor = i + 1; // mover el cursor hacia atrás (e) ElementData [lastret = i]; // Establezca la posición de acceso y devuelva este valor} // Elimine el elemento public void remove () {if (lastret <0) tire nueva ilegalstateException (); checkforComodification (); // verifique si la matriz está modificada, intente {arrayList.this.remove (LASTRET); cursor = latret; Lastret = -1; esperadoModCount = modCount; } Catch (indexOuTOfBoundsexception ex) {tirar nueva concurrenteModificationException (); }} @Override @SupplesWarnings ("no está facturado") public void foreachremaning (Consumer <? Super E> Consumer) {Objects.RequirenonNull (Consumer); final int tize = arrayList.this.size; int i = cursor; if (i> = size) {return; } objeto final [] elementData = ArrayList.This.ElementData; if (i> = elementData.length) {lanzar nueva concurrenteModificationException (); } while (I } cursor = i; LASTRET = I - 1; checkforcomodification (); } // Verifique si la matriz está modificada final void checkforcomodification () {if (modCount! = EsperadoModCount) tire nuevo concurrentModificationException (); }} // listiterator Iterator implementa la clase privada listitr extiende ITR implementos listiterator <E> {listitr (int index) {super (); cursor = índice; } public boolean Hasprevious () {return cursor! = 0; } public int NextIndex () {return cursor; } public int anteriorindex () {return cursor - 1; } @Suppleswarnings ("sin verificar") public e anterior () {checkforcomOdification (); int i = cursor - 1; if (i <0) tirar nueva nosuchelementException (); Objeto [] elementData = ArrayList.This.ElementData; if (i> = elementData.length) tire nuevo concurrentModificationException (); cursor = i; return (e) elementData [lastret = i]; } set public void (e e) {if (lastret <0) tirar nueva ilegalStateException (); checkforcomodification (); Pruebe {ArrayList.This.Set (LASTRET, E); } Catch (indexOuTOfBoundsexception ex) {tirar nueva concurrenteModificationException (); }} public void add (e e) {checkforComodification (); intente {int i = cursor; ArrayList.THIS.Add (i, e); cursor = i + 1; Lastret = -1; esperadoModCount = modCount; } Catch (indexOuTOfBoundsexception ex) {tirar nueva concurrenteModificationException (); }}} // Subarrray de retorno de la lista pública del rango especificado <E> Sublist (int fromIndex, int toIndex) {sublistrangeCheck (fromIndex, toIndex, size); devolver nuevo sublista (this, 0, fromindex, toindex); } // verificación de seguridad void static sublistrangeCheck (int fromIndex, int toIndex, int size) {if (fromIndex <0) tirar nueva indexOutofBoundsexception ("fromIndex =" + fromIndex); if (toIndex> size) tire nuevo índiceuToUfBoundsexception ("toIndex =" + toIndex); if (fromIndex> toIndex) tire nueva ilegalArgumentException ("fromIndex (" + fromIndex + ")> toIndex (" + toIndex + ")"); } // Subadray Private Class Sublist extiende AbstractList <E> Implementa RandomAccess {private final de abstracto final <E> parent; Private final int ParentOffset; Private Final Int Offset; tamaño int; Sublist (AbstractList <E> Parent, Int Offset, int fromIndex, int toIndex) {this.parent = parent; this.ParentOffset = fromIndex; this.offset = offset + fromIndex; this.size = toIndex - fromIndex; this.modcount = arrayList.this.modcount; } public e set (int index, e e) {rangeCheck (index); checkforcomodification (); E OldValue = ArrayList.THIS.ElementData (offset + índice); ArrayList.THIS.ElementData [offset + index] = e; devolver OldValue; } public e get (int index) {rangeCheck (index); checkforcomodification (); return arrayList.this.ElementData (offset + índice); } public int size () {checkforComodification (); devolver esto.size; } public void add (int index, e e) {rangecheckforadd (index); checkforcomodification (); parent.add (ParentOffset + índice, e); this.modcount = parent.modcount; this.size ++; } public e remove (int index) {rangeCheck (index); checkforcomodification (); E resultado = parent.remove (parentoffset + índice); this.modcount = parent.modcount; esto.size--; resultado de retorno; } Removerange void protegido (int fromIndex, int toIndex) {checkforcomodification (); parent.removerange (parentoffset + fromindex, parentoffset + toindex); this.modcount = parent.modcount; this.size - = toindex - fromIndex; } public boolean addall (colección <? extiende e> c) {return addall (this.size, c); } public boolean addall (int index, colección <? extiende e> c) {rangecheckforadd (index); int csize = C.Size (); if (csize == 0) return false; checkforcomodification (); parent.addall (ParentOffset + índice, c); this.modcount = parent.modcount; this.size += csize; devolver verdadero; } public Iterator <E> iterator () {return listIterator (); } public listIterator <E> listIterator (Final int index) {checkforComOdification (); rangecheckforadd (índice); final int offset = this.Offset; return New ListIterator <E> () {int cursor = index; int lastret = -1; int esperadoModCount = ArrayList.THIS.MODCOUNT; public boolean Hasnext () {return cursor! = sublist.this.size; } @Suppleswarnings ("sin verificar") public e next () {checkforComOdification (); int i = cursor; if (i> = sublist.this.size) tirar nueva nosuchelementException (); Objeto [] elementData = ArrayList.This.ElementData; if (offset + i> = elementData.length) tire nuevo concurrentModificationException (); cursor = i + 1; return (e) elementData [offset + (latret = i)]; } public boolean Hasprevious () {return cursor! = 0; } @Suppleswarnings ("sin verificar") public e anterior () {checkforcomOdification (); int i = cursor - 1; if (i <0) tirar nueva nosuchelementException (); Objeto [] elementData = ArrayList.This.ElementData; if (offset + i> = elementData.length) tire nuevo concurrentModificationException (); cursor = i; return (e) elementData [offset + (latret = i)]; } @Suppleswarnings ("sin control") public void foreachremaning (consumidor <? Super E> Consumer) {Objects.RequirenonNull (Consumer); size int tize = sublist.this.size; int i = cursor; if (i> = size) {return; } objeto final [] elementData = ArrayList.This.ElementData; if (offset + i> = elementData.length) {lanzar nueva concurrenteModificationException (); } while (I } // Actualizar una vez al final de la iteración para reducir el tráfico de la escritura del montón = cursor = i; checkforcomodification (); } public int NextIndex () {return cursor; } public int anteriorindex () {return cursor - 1; } public void remove () {if (LASTRET <0) Lanzar nueva ilegalStateException (); checkforcomodification (); intente {sublist.this.remove (latret); cursor = latret; Lastret = -1; esperadoModCount = ArrayList.THIS.MODCOUNT; } Catch (indexOuTOfBoundsexception ex) {tirar nueva concurrenteModificationException (); }} Public void set (e e) {if (lastret <0) tirar nueva ilegalStateException (); checkforcomodification (); intente {arrayList.this.set (offset + latret, e); } Catch (indexOuTOfBoundsexception ex) {tirar nueva concurrenteModificationException (); }} public void add (e e) {checkforComodification (); intente {int i = cursor; Sublist.this.add (i, e); cursor = i + 1; Lastret = -1; esperadoModCount = ArrayList.THIS.MODCOUNT; } Catch (indexOuTOfBoundsexception ex) {tirar nueva concurrenteModificationException (); }} final void checkforComOdification () {if (esperadoModCount! = ArrayList.THIS.MODCOUNT) Lanzar nueva concurrenteModificationException (); }}; } Lista pública <E> sublist (int fromIndex, int toIndex) {sublistrangecheck (fromIndex, toindex, size); devolver nuevo sublista (esto, offset, fromindex, toindex); } private void rangeCheck (int index) {if (index <0 || index> = this.size) tire el nuevo indexOUTOFBoundSException (outOfBoundSMSG (index)); } private void rangecheckforAdd (int index) {if (index <0 || index> this.size) tire nuevo indexOutOfBoundSException (outOfBoundSMSG (index)); } private String outOfBoundSmsg (int index) {return "índice:"+index+", tamaño:"+this.size; } private void checkforComOdification () {if (arrayList.this.modcount! = this.modcount) tire nueva concurrentModificationException (); } public spliterator <E> Splitterator () {checkforComodification (); devolver nuevo ArrayListsPliterator <E> (ArrayList.This, Offset, Offset + this.size, this.modcount); }} @Override public void foreach (Consumer <? Super E> Action) {Objects.RequirenonNull (Action); Final int esperadomodCount = modCount; @SupessWarnings ("sin control") final e [] elementData = (e []) this.ElementData; size int tize = this.size; for (int i = 0; modcount == esperadoModCount && i <size; i ++) {Action.accept (elementData [i]); } if (modCount! = esperadoModCount) {lanzar nueva concurrenteModificationException (); }}/** * crea A <em> <a href = "Spliterator.html#Binding" rel = "externo nofollow"> Binding tardío </a> </em> * y <em> Fail-Fast </em> {@Link Splitriter} sobre los elementos en esta * lista. * * <p> El {@code Splititerator} informes {@link Splitriter#Sized}, * {@link Splitriter#subsense} y {@link Splitriter#ordenado}. * Las implementaciones anulantes deben documentar el informe de valores característicos * adicionales. * * @return a {@code Splitriter} sobre los elementos en esta lista * @since 1.8 */ @Override public Splitriter <E> Splitterator () {return New ArrayListsPliterator <> (this, 0, -1, 0); } /** Spliterator inicializado inicializado de división basada en índice * /clase final estática ArrayListsPliterator <E> Implementa Spliterator <E> { / * * Si ArrayLists eran inmutables o estructuralmente inmutables (no * agrega, elimina, etc.) podríamos implementar sus divisoradores * con matrices. En cambio, detectamos tanto * interferencia durante el recorrido como práctico sin * sacrificar mucho rendimiento. Confiamos principalmente en * modos de modificación. Estos no están garantizados para detectar la concurrencia * violencia, y a veces son demasiado conservadores sobre * interferencia dentro del hilo, sino que detectan suficientes problemas para * valer la pena en la práctica. Para llevar a cabo esto, (1) perezosamente * Inicializamos la cerca y esperamos Modcount hasta el último * punto * en el que necesitamos comprometernos con el estado en el que estamos revisando *; mejorando así la precisión. (Esto no se aplica a * sublistas, que crean divisoradores con valores actuales no perezosos *). (2) Realizamos solo una sola verificación * ConcurrenteModificationException al final de Foreach * (el método más sensible al rendimiento). Al usar foreach * (a diferencia de los iteradores), normalmente solo podemos detectar * interferencia después de las acciones, no antes. Otras controles de activación de * CME se aplican a todas las otras posibles violencia * de suposiciones, por ejemplo, una matriz de elementos nulos o demasiado pequeños * dado su tamaño (), que solo podría haber * ocurrido debido a la interferencia. Esto permite que el bucle interno * de foreach se ejecute sin más verificaciones, y * simplifica la resolución lambda. Si bien esto implica un número * de cheques, tenga en cuenta que en el caso común de * list.stream (). Foreach (a), ninguna comprobación u otra computación * ocurre en cualquier lugar que no sea el interior de la misma. Los otros * métodos de uso menos a menudo no pueden aprovechar la mayoría de * estas corrientes de transmisión. */ Lista de ArrayList Final Private Final; Índice de int privado; // índice de corriente, modificado en una valla int -int -ints ints intense de avance/dividido; // -1 hasta que se use; luego un último índice pasado privado int esperadomodcount; // Inicializado cuando la cerca establece/ ** Cree un nuevo Spliterator que cubra el rango dado*/ ArrayListsPliterator (ArrayList <E> List, Int Origin, Int Fence, Int LeardModCount) {this.list = list; // ok si es nulo a menos que se atravesara esto.index = origen; this.fence = cerca; this.EppectedModCount = esperadoModCount; } private int getfence () {// Inicializar la cerca para el tamaño en el primer uso int hi; // (una variante especializada aparece en el método foreach) ArrayList <E> LST; if ((hi = cerca) <0) {if ((lst = list) == null) hi = val = 0; else {esperadoModCount = lst.modcount; hola = valla = lst.size; }} return HI; } public arrayListsPliterator <E> trysplit () {int hi = getFence (), lo = index, mid = (lo + hi) >>> 1; return (lo> = Mid)? nulo: // divide el rango por la mitad a menos que sea demasiado pequeño ArrayListsPliterator <E> (Lista, LO, índice = Mid, esperadoModCount); } public boolean tryAdvance(Consumer<? super E> action) { if (action == null) throw new NullPointerException(); int hi = getFence(), i = index; if (i < hi) { index = i + 1; @SuppressWarnings("unchecked") E e = (E)list.elementData[i]; action.accept(e); if (list.modCount != expectedModCount) throw new ConcurrentModificationException(); return true; } return false; } public void forEachRemaining(Consumer<? super E> action) { int i, hi, mc; // hoist accesses and checks from loop ArrayList<E> lst; Object[] a; if (action == null) throw new NullPointerException(); if ((lst = list) != null && (a = lst.elementData) != null) { if ((hi = fence) < 0) { mc = lst.modCount; hi = lst.size; } else mc = expectedModCount; if ((i = index) >= 0 && (index = hi) <= a.length) { for (; i < hi; ++i) { @SuppressWarnings("unchecked") E e = (E) a[i]; action.accept(e); } if (lst.modCount == mc) return; } } throw new ConcurrentModificationException(); } public long estimateSize() { return (long) (getFence() - index); } public int characteristics() { return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED; } } @Override public boolean removeIf(Predicate<? super E> filter) { Objects.requireNonNull(filter); // figure out which elements are to be removed // any exception thrown from the filter predicted at this stage // will leave the collection unmodified int removeCount = 0; final BitSet removeSet = new BitSet(size); final int expectedModCount = modCount; final int size = this.size; for (int i=0; modCount == expectedModCount && i < size; i++) { @SuppressWarnings("unchecked") final E element = (E) elementData[i]; if (filter.test(element)) { removeSet.set(i); removeCount++; } } if (modCount != expectedModCount) { throw new ConcurrentModificationException(); } // shift surviving elements left over the spaces left by removed elements final boolean anyToRemove = removeCount > 0; if (anyToRemove) { final int newSize = size - removeCount; for (int i=0, j=0; (i < size) && (j < newSize); i++, j++) { i = removeSet.nextClearBit(i); elementData[j] = elementData[i]; } for (int k=newSize; k < size; k++) { elementData[k] = null; // Let gc do its work } this.size = newSize; if (modCount != expectedModCount) { throw new ConcurrentModificationException(); } modCount++; } return anyToRemove; } @Override @SuppressWarnings("unchecked") public void replaceAll(UnaryOperator<E> operator) { Objects.requireNonNull(operator); final int expectedModCount = modCount; final int size = this.size; for (int i=0; modCount == expectedModCount && i < size; i++) { elementData[i] = operator.apply((E) elementData[i]); } if (modCount != expectedModCount) { throw new ConcurrentModificationException(); } modCount++; } @Override @SuppressWarnings("unchecked") public void sort(Comparator<? super E> c) { final int expectedModCount = modCount; Arrays.sort((E[]) elementData, 0, size, c); if (modCount != expectedModCount) { throw new ConcurrentModificationException(); } modCount++; }}Resumir
The above is all about ArrayList source code analysis in Java programming, and I hope it will be helpful to everyone. Los amigos interesados pueden continuar referiéndose a otros temas relacionados en este sitio. Si hay alguna deficiencia, deje un mensaje para señalarlo. ¡Gracias amigos por su apoyo para este sitio!