¿Cuál es la capacidad inicial predeterminada de un objeto?
Los objetos de lista de ArrayList se almacenan esencialmente en una matriz de referencia. Algunas personas piensan que las matrices tienen un "mecanismo de crecimiento automático" que puede cambiar de tamaño automáticamente. Formalmente hablando, las matrices no se pueden cambiar.
El tamaño en realidad simplemente cambia el puntero de la matriz a la que se hace referencia. Echemos un vistazo a cómo Java implementa la clase ArrayList.
1. La esencia de la clase ArrayList
La capa inferior de ArrayList se implementa mediante una matriz de tipo Objeto. Cuando se utiliza el constructor sin parámetros para generar un objeto ArrayList,
en realidad, se generará una matriz de tipo Objeto con una longitud de 10 en la parte inferior.
En primer lugar, ArrayList define un elemento de matriz privado no serializado para almacenar la lista de objetos de ArrayList (tenga en cuenta que solo se definen los no inicializados):
¿Privado? ¿Temporario? objeto[]? elementData
En segundo lugar, cree una instancia de la matriz elementData especificando la capacidad inicial o convirtiendo la colección especificada en una matriz de referencia. Si no se especifica, la capacidad inicial predeterminada es 10.
Creación de instancias. Crear una instancia de la matriz privada por adelantado y luego sobrescribir la matriz original con el método copyOf es la clave para cambiar automáticamente el tamaño de ArrayList. Algunas personas dicen que ArrayList es una matriz compleja, pero yo creo que ArrayList es una combinación de métodos sistemáticos sobre matrices.
El código fuente del método de construcción ArrayList es el siguiente:
//? Construye una lista vacía con una capacidad inicial especificada.
¿Público? ArrayList(int? capacidad inicial)? {
super();
¿Si? (¿Capacidad inicial? lt? 0)
¿Lanzar? ¿Nuevo? IllegalArgumentException("¿Ilegal? Capacidad:?" capacidad inicial);
this.elementData? =?¿Nuevo? objeto[capacidad inicial]; //La propiedad apunta a una nueva matriz temporal con capacidad inicial.
}
//?Construya una lista vacía usando una capacidad inicial de 10.
¿Público? Lista de matrices()? {
This(10);
}
/?* Construye una lista que contiene los elementos de la colección especificada devueltos en orden por el iterador de la colección. .
*?@param? ¿do? Una colección cuyos elementos se colocarán en la lista t.
*?@lanzamientos? ¿Excepción de puntero nulo? Si la colección especificada es. Vacío
*/
¿Público? ArrayList (establecer lt se extiende? ¿E gt? c)? {
elementoDatos? =?c . to array();//Inicializa la matriz elementData con una colección.
¿Tamaño? =?elementData.length
¿Si? (elementData.getClass()?!=?Object[].Class)
elementData? =?Arrays.copyOf(elementData, size,?Object[].Class);
}
En segundo lugar, ArrayList implementa un mecanismo para cambiar automáticamente el tamaño.
Para implementar este mecanismo, Java introduce los conceptos de capacidad y tamaño para distinguir la longitud de la matriz. Para garantizar que los usuarios agreguen nuevos objetos de lista, Java establece una capacidad mínima mínima.
Normalmente, es mayor que el número de objetos de la lista, por lo que, aunque Capacidad es la longitud de la matriz subyacente, no tiene sentido para el usuario final. lista de almacenamiento de tamaño.
Lo que necesita el usuario final es número de objetos. Para evitar errores del usuario, esta propiedad está configurada como privada, pero se puede obtener mediante size().
A continuación, se analiza el mecanismo de cambio de tamaño automático de ArrayList en tres situaciones: la inicialización de ArrayList y la adición y eliminación de sus objetos de lista.
1, valores iniciales de capacidad y tamaño.
No es difícil ver en el código fuente del método de construcción ArrayList proporcionado anteriormente que la capacidad inicial puede ser especificada directamente por el usuario o almacenada en una colección especificada por el usuario.
Determinar el número de objetos de almacenamiento. Si no se especifica, el sistema por defecto es 10. El tamaño se declara como una variable int y el valor predeterminado es 0. Cuando el usuario especifica una Colección para crear una ArrayList, el valor del tamaño es igual a.
Capacidad inicial.
Método 2.add()
El código fuente de este método es el siguiente:
¿Público? ¿Booleano? ¿Agregar(E?e)? {
asegurarCapacityInternal(tamaño? ?1);
elementData[tamaño]? =?e; //Al agregar un objeto, aumenta el tamaño por sí solo.
¿Volver? True;
}
La función sureCapacityInternal llamada en el método se utiliza principalmente para ajustar la capacidad y modificar la orientación de la matriz elementData. Implica la invocación de tres métodos, cuyo núcleo es el método grow:
¿Privado? ¿Vacío? asegurarCapacityInternal(int?minCapacity)? {
modcount; La clase principal AbstractList definida en ArrayList se utiliza para almacenar el número de modificaciones de la estructura.
//?¿Conciencia desbordada? Contraseña
¿Y si? (minCapacity? -?elementData.length? gt? 0)
crecer(capacidad mínima);
}
¿Privado? ¿Vacío? crecer(int?minCapacity)? {
//?¿Conciencia desbordada? Contraseña
int? ¿Capacidad antigua? =?elementData.length
int? ¿Nueva capacidad? =?Capacidad anterior? ?(oldCapacity? gt gt? 1); // La nueva capacidad se expande a 65438, que es 0,5 veces la capacidad original. El desplazamiento a la derecha en una posición está relacionado con el valor original dividido por 2.
¿Y si? (¿nuevaCapacidad?-?minCapacidad?lt?0)
¿Nueva capacidad? =?minCapacity
¿Y si? (newCapacity?-?MAX_ARRAY_SIZE? gt?0)
¿Nueva capacidad? =?gran capacidad(capacidad mínima);
//?minCapacity? ¿Sí? ¿generalmente? ¿cerca? ¿A dónde ir? tamaño,? ¿Así que lo que? ¿este? ¿Sí? ¿respuesta? Ganador:
elementData? =?Arrays.copyOf(elementData, nueva capacidad);
}
¿Privado? ¿Electricidad estática? int? enormeCapacidad(int?minCapacity)? {
¿Y si? (¿minCapacity? lt? 0)?/?//?Inundación
¿Lanzar? ¿Nuevo? error de memoria insuficiente();
¿Volver? (¿minCapacity? gt? Tamaño máximo de matriz)
Entero. ¿MAX_VALUE? :
Tamaño máximo de matriz; //MAX_ARRAY_SIZE y Entero. MAX_VALUE es una constante. Consulte las notas a continuación para obtener más detalles.
}
A través del código anterior, sabemos que Java aumenta automáticamente el tamaño de ArrayList. La idea es: al agregar un objeto a ArrayList, el número original de objetos es. aumentado en 1. Si es mayor que la longitud original de la matriz subyacente, se actualizará a la longitud adecuada.
Cree una copia de la matriz original y modifique la matriz original para que apunte a esta nueva matriz. La matriz original se descarta automáticamente (el mecanismo de recolección de basura de Java la reciclará automáticamente). El tamaño agrega un objeto a la matriz y aumenta en 1.
Nota:
//La constante definida en esta clase se utiliza para asignar el tamaño máximo de la matriz. ¿Alguno? Las máquinas virtuales conservan prefijos en las matrices y los intentos de asignar una matriz más grande pueden generar un OutOfMemoryError para la matriz solicitada:
El tamaño excede los límites de la máquina virtual.
¿Privado? ¿Electricidad estática? finales? int? ¿MAX_ARRAY_SIZE? =?entero.
¿MAX_VALUE? -?8;
//En la clase java.lang.Integer, las constantes MIN_VALUE y MAX_VALUE son las siguientes:
Pública? ¿Electricidad estática? finales? int? ¿Valor mínimo? =?0x80000000//El límite inferior del rango de valores enteros: -2147483648
¿Público? ¿Electricidad estática? finales? int? ¿MAX_VALUE? =?0x7fffffff//El límite superior del rango de valores enteros: 2147483647
//En java.util.AbstractList, modCount se define de la siguiente manera:
¿Protegido? ¿Temporario? int? modCount? =?0;
3. Método Remove()
Un código fuente de este método de reconstrucción es el siguiente (no entraré en detalles sobre los demás):
¿Público? ¿mi? eliminar (int? índice)? {
rangeCheck(index);
modcount;
e? valor antiguo? =?elementData(índice);
int? num¿Movido? =?Tamaño? -?¿índice? -?1;
¿Si? (numMoved? gt? 0)
System.arraycopy(elementData, index 1,?elementData,?index,
num move); //Mover el siguiente objeto de lista hacia adelante.
elementData[ - tamaño]? =?nulo? ///?La matriz avanza un bit, el tamaño se reduce automáticamente y la posición desocupada se establece en nula. El recolector de basura es responsable de destruir objetos específicos.
¿Volver? valor anterior;
}
¿Privado? ¿Vacío? rangeCheck(int? índice)? {//verificación de límites
¿Y si? (¿Índice? lt? 0?||?Index? gt=?this.size)
¿Lanzar? ¿Nuevo? IndexOutOfBoundsException(outOfBoundsMsg(índice));
}
e? elementData(int? índice)? {//Obtiene el objeto en el índice especificado.
¿Volver? (MI)? element data[index];
}
Al estudiar el código fuente de remove(), podemos ver fácilmente que el núcleo de cambiar el tamaño de ArrayList es similar al add( ) método.
Además, si es necesario, el usuario también puede especificar la capacidad de la instancia de ArrayList, lo que puede reducir efectivamente los costos de tiempo. Esto se logra llamando al código fuente asegurarCapacityInternal
como se muestra a continuación:
Público? ¿Vacío? asegurarCapacidad(int?minCapacity)? {
¿Y si? (minCapacity? gt? 0)
ensureCapacityInternal(min capacidad);
}
Debido a que el tamaño es privado, Java proporciona una forma de acceder a él Método:
¿Público? int? tamaño()? {
checkforcomedification();
¿Regresión? this.size
}
En resumen, cuando el usuario agrega un objeto a ArrayList, Java siempre necesita calcular primero si la capacidad es adecuada. copie la matriz original en la matriz creada con la capacidad especificada.
En la nueva matriz, reasigne la variable de la matriz original para que apunte a la nueva matriz. Al mismo tiempo el tamaño aumenta en 1. Al eliminar un objeto, primero use el método de copia para mover el objeto detrás del índice especificado hacia adelante 1 posición (si
Si hay uno), luego devuelva la posición vacante a cero y entréguela al recolector de basura para su destrucción. Reduce el tamaño en 1 y listo.