Surge una pregunta estándar: ¿cómo inicializar una lista? El siguiente código no funcionará: generará un error de compilación: Es posible que los nombres de las variables locales no se hayan inicializado . La especificación de Java requiere que todas las variables locales (las que existen en la pila) se inicialicen con los valores apropiados. Así es como puedes hacerlo: Sin duda la lista debe estar inicializada. Puede crear la lista en la primera línea o puede hacer algo más inteligente y utilizar la inicialización diferida como hicimos en el método getAllNames() . En este caso, la lista sólo se creará cuando sea necesario; si no se cumplen las condiciones iniciales, la lista nunca aparecerá en el montón. Aquí llegamos a la pregunta principal: ¿qué tamaño debemos establecer para la lista? La mejor opción es darle el tamaño exacto. Por ejemplo: en este caso, se deben devolver exactamente n nombres y, como consecuencia, se crea una colección de n elementos. Sin embargo, no siempre se conoce el valor exacto de n . Incluso en el ejemplo dado, ¿qué pasaría si n=1000 y solo hubiera 100 nombres disponibles? Cuando se trabaja con colecciones, el método más popular es llamar al constructor predeterminado. Si miras el código fuente de Java (versión 1.6) como puedes ver, por defecto se crea una lista de 10 elementos . Es decir, podemos utilizar con seguridad el constructor predeterminado cuando no planeamos almacenar más de 10 elementos en la lista. ¿Qué sucede si intentas agregar el undécimo elemento? Bueno, nada malo... el elemento se agregará exitosamente. Mire el método: el tamaño de la matriz está controlado por el método sureCapacity . El tamaño aumenta 1,5 veces . Se crea una nueva matriz y los elementos se mueven a ella. Si establecemos el tamaño en 10, entonces en el undécimo elemento:
public List
getAllNames() { List
names; if (/*необходимые условия выполнены*/) { names = new ArrayList
(); /*заполнение списка*/ } return names; }
List
names = null; List
names = new ArrayList
(); List
names = new ArrayList
(0); List
names = new ArrayList
(size);
public List
getTopNames (int n) { List
names = null; if ( /*необходимые условия выполнены*/) { names = new ArrayList
(n); /*заполнение списка*/ } return names; }
names = new ArrayList
();
/** * Конструирует пустой список с указанной начальной емкостью. * * @param initialCapacity начальная емкость списка * @exception IllegalArgumentException если указанная начальная емкость отрицательна * */ public ArrayList(int initialCapacity) { super(); if (initialCapacity < 0) this.elementData = new Object[initialCapacity]; } /** * Конструирует пустой список с начальной емкостью, равной 10. */ public ArrayList() { this(10); }
public Boolean add(E e) { ensureCapacity(size + 1); //увеличивает modCount!! elementData[size++] = e; return true; }
public void ensureCapacity (int minCapacity) { modCount++; int oldCapacity = elementData.length; if (minCapacity > oldCapacity) { throw new IllegalArgumentException(“Illegal Capacity: ” + initialCapacity); Object oldData[] = elementData; int newCapacity = (oldCapacity * 3) / 2 + 1; if (newCapacity < minCapacity) newCapacity = minCapacity; // minCapacity обычно ближе к размеру, так что это беспроигрышно: elementData = Arrays.copyOf(elementData, newCapacity); } }
- el tamaño cambia a 10 * 3 / 2 + 1 = 16
- siguiente aumento = 16 * 3 / 2 + 1 = 25
- siguiente aumento = 25 * 3/2 + 1 = 39 y así sucesivamente.
- Cree una colección solo cuando la necesite ; de lo contrario, inicialícela como nula o use Collections.EMPTY_LIST .
- Si conoce el tamaño exacto requerido , especifíquelo en el constructor de la colección.
- Si está seguro de que la cantidad de elementos no excederá los 10 , no dude en utilizar el constructor predeterminado.
- El riesgo asociado con la creación de una colección de tamaño cero es que la frecuencia de creación de nuevas matrices y copia de datos puede ser mayor. Debe pensar con mucho cuidado si el beneficio de utilizar colecciones de tamaño cero es realmente tan grande .
- Si inicializó una colección demasiado grande al comienzo del método y desea reducirla, existe el método trimToSize() .
GO TO FULL VERSION