Sorge una domanda standard: come inizializzare un elenco? Il codice seguente non funzionerà: Risulterà in un errore di compilazione: I nomi delle variabili locali potrebbero non essere stati inizializzati . La specifica Java richiede che tutte le variabili locali (quelle presenti nello stack) siano inizializzate con valori appropriati. Ecco come puoi farlo: Senza dubbio, l'elenco deve essere inizializzato. Puoi creare l'elenco sulla prima riga oppure puoi fare qualcosa di più intelligente e utilizzare l'inizializzazione pigra come abbiamo fatto nel metodo getAllNames() . In questo caso l'elenco verrà creato solo quando necessario: se le condizioni iniziali non vengono soddisfatte, l'elenco non verrà mai visualizzato nell'heap. Qui arriviamo alla domanda principale: quale dimensione dobbiamo impostare per la lista? L'opzione migliore è dargli la dimensione esatta. Ad esempio: In questo caso devono essere restituiti esattamente n nomi e di conseguenza viene creata una raccolta di n elementi. Tuttavia, il valore esatto di n non è sempre noto. Anche nell'esempio fornito, cosa accadrebbe se n=1000 e ci fossero solo 100 nomi disponibili? Quando si lavora con le raccolte, il metodo più diffuso è chiamare il costruttore predefinito. Se guardi il codice sorgente Java (versione 1.6) Come puoi vedere, per impostazione predefinita viene creata una lista di 10 elementi . Cioè, possiamo tranquillamente utilizzare il costruttore predefinito quando non prevediamo di memorizzare più di 10 elementi nell'elenco. Cosa succede se provi ad aggiungere l'undicesimo elemento? Beh, niente di male... l'elemento verrà aggiunto con successo. Guarda il metodo: la dimensione dell'array è controllata dal metodo verifyCapacity . La dimensione aumenta di 1,5 volte . Viene creato un nuovo array e gli elementi vengono spostati al suo interno. Se impostiamo la dimensione su 10, quindi sull'undicesimo 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); } }
- la dimensione cambia in 10 * 3 / 2 + 1 = 16
- aumento successivo = 16 * 3 / 2 + 1 = 25
- aumento successivo = 25 * 3 / 2 + 1 = 39 e così via.
- Crea una raccolta solo quando ne hai bisogno , altrimenti inizializzala su null o utilizza Collections.EMPTY_LIST .
- Se conosci la dimensione esatta richiesta , specificala nel costruttore della raccolta.
- Se sei sicuro che il numero di elementi non supererà 10 , sentiti libero di utilizzare il costruttore predefinito.
- Il rischio associato alla creazione di una raccolta di dimensione zero è che la frequenza di creazione di nuovi array e di copia dei dati potrebbe essere più elevata. È necessario riflettere molto attentamente se il vantaggio derivante dall'utilizzo di raccolte a dimensione zero è davvero così grande .
- Se hai inizializzato una raccolta troppo grande all'inizio del metodo e vuoi ridurla, esiste il metodo trimToSize() .
GO TO FULL VERSION