java - imprimir - Capacidad inicial de ArrayList e IndexOutOfBoundsException
imprimir arraylist java (3)
Esta pregunta ya tiene una respuesta aquí:
- Tamaño inicial para ArrayList 12 respuestas
Considere este código de muestra:
List<String> myList = new ArrayList<String>(7);
myList.add(5, "Hello");
myList.removeAll(Collections.singleton(null));
System.out.println(myList.size() + " objects:" );
for (String s : myList) {
System.out.println("/t" + s);
}
myList
se inicializa con una capacidad inicial de 7, luego la siguiente línea intenta agregar la cadena "Hello" en la posición 5. Esto arroja una excepción IndexOutOfBoundsException:
Excepción en el hilo "principal" java.lang.IndexOutOfBoundsException: Índice: 5, Tamaño: 0
Revisé esta pregunta sobre qué significa "capacidad inicial" en términos de una lista de arreglos. Entiendo que este constructor particular está asignando espacio para 7 elementos de cadena, y si tratamos de agregar 8 elementos a la lista, tendrá que asignar más espacio.
Lo que no entiendo es por qué no crea una lista "vacía" de tamaño 7, con valores nulos en cada índice, similar a lo que sucedería si String[] myArray = new String[7]
. Recuerdo que aprendí que ArrayList es la implementación de Java de una matriz dinámica, así que esperaría un tipo similar de comportamiento. Si en realidad no tengo espacio para 7 Strings asignados cuando declaro una new ArrayList<String>(7)
, ¿qué está sucediendo realmente?
Lo que no entiendo es por qué no crea una lista "vacía" de tamaño 7, con valores nulos en cada índice, similar a lo que sucedería si declaramos String [] myArray = new String [7].
Eso sería útil en algunos casos ... y no útil en otros. Muy a menudo tiene un límite superior del tamaño de la lista que va a crear (o al menos una suposición) pero luego lo rellena ... y no quiere tener una lista que tiene el tamaño incorrecto. .. por lo que tendrías que mantener un índice mientras "estableces" los valores, y luego establecer el tamaño después.
Recuerdo que aprendí que ArrayList es la implementación de Java de una matriz dinámica, así que esperaría un tipo similar de comportamiento.
No, realmente no es. Es una lista que puede redimensionarse y utiliza una matriz detrás de la escena. Intenta no pensar en ello como una matriz.
Si en realidad no tengo espacio para 7 Strings asignados cuando declaro una nueva
ArrayList<String>(7)
, ¿qué está sucediendo realmente?
Usted tiene espacio para 7 cadenas de referencias. El tamaño del búfer (es decir, la capacidad) es de al menos 7, pero el tamaño lógico de la lista sigue siendo 0: no le ha agregado nada. Es como si tuviera una hoja de papel lo suficientemente larga para 7 líneas, pero aún no ha escrito nada.
Si desea una lista prellenada, puede escribir fácilmente un método para crear una:
public static List<T> createPrefilledList(int size, T item) {
ArrayList<T> list = new ArrayList<T>(size);
for (int i = 0; i < size; i++) {
list.add(item);
}
}
Existe una diferencia entre la capacidad inicial de una matriz y su tamaño (es decir, la cantidad de elementos que contiene la matriz). Es su tamaño el que se usa para determinar si está intentando acceder a un índice que está fuera de los límites.
Aquí está el método ArrayList.java
que hace esta comprobación:
private void rangeCheckForAdd(int index) {
if (index < 0 || index > this.size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
Como puede ver, no tiene nada que ver con la capacidad inicial de la matriz. Se basa únicamente en la cantidad de elementos que contiene.
La capacidad inicial solo hace una cosa: da una sugerencia (no un requisito) de cuán grande debe ser la matriz de respaldo. Lógicamente, no hay diferencia entre qué operaciones están permitidas con o sin la sugerencia, o cuál es la sugerencia. Los únicos cambios serán en qué operaciones internas podrían ocurrir o no ocurrir como una sugerencia de optimización.
Solo puede ''agregar'' así a posiciones que ya existen en la matriz. Los elementos antes de la posición 5 aún no existen, por lo que arroja una excepción. Desde el Javadoc :
Lanza: IndexOutOfBoundsException - si el índice está fuera de rango (índice <0 || index> tamaño ())