Tra le varie collezioni contenute nel Java Collections Framework della piattaforma Standard Edition di Java, esistono le due ben note classi java.util.ArrayList
e java.util.Vector
. Sono due “collezioni” molto simili come concetti e funzionalità, quindi si prestano molto bene ad essere messe a confronto.
Non sono certamente il primo che si occupa di fare una analisi di questo tipo ma con questo breve articolo l’obiettivo è di esporre in maniera chiara e puntuale tutte le similitudini e le differenze più rilevanti che si possono riscontrare su queste due collezioni.
Similitudini tra ArrayList e Vector
-
Entrambe le collezioni rappresentano una sequenza lineare di elementi indirizzabili tramite un indice numerico di tipo
int
che va da 0 a lunghezza-1 (dove lunghezza è il risultato del metodosize()
). -
Entrambe le collezioni sono espandibili e ridimensionabili “dinamicamente”, come avviene in generale anche per tutte le altre collezioni.
-
Entrambe le collezioni sono basate internamente su un singolo array che viene gestito a “capacità più espansa”, cioè per la maggior parte del tempo la capacità fisica dell’array interno è ben maggiore rispetto al numero “logico” di elementi realmente presenti. Quando la capacità fisica dell’array non è più sufficiente, la collezione crea un nuovo array più ampio, copiandoci dentro gli elementi dal “vecchio” array che viene poi alla fine rimpiazzato dal nuovo.
-
Entrambe le collezioni permettono l’inserimento di valori
null
. -
Entrambe le collezioni a partire dal JDK 5 sono classi “generiche” nel senso che sfruttano i generics introdotti in Java 5 e quindi possono essere utilizzate parametrizzate (es.
ArrayList<String>
eVector<String>
). -
Entrambe le collezioni implementano (direttamente o indirettamente) le interfacce:
Cloneable
Collection<E>
Iterable<E>
(a partire dal JDK 5)List<E>
RandomAccess
Serializable
-
Entrambe le collezioni forniscono un iterator (intendendo qui in generale sia
java.util.Iterator
, siajava.util.ListIterator
) che ha il comportamento indicato con l’espressione fail-fast, cioè la iterazione fallisce lanciando l’eccezionejava.util.ConcurrentModificationException
nel momento in cui l’iteratore riesce a determinare che la collezione è stata modificata strutturalmente utilizzando qualunque metodo di modifica eccetto quelli forniti specificatamente daIterator
/ListIterator
.
Differenze tra ArrayList e Vector
-
Vector
esiste dal JDK 1.0 mentreArrayList
esiste dal JDK 1.2 (versione in cui è stato introdotto il Java Collections Framework).Vector
è una collezione definita “legacy” ed è tuttora mantenuta nel framework principalmente per motivi di compatibilità. -
Vector
ha un costruttore che riceve initialCapacity e capacityIncrement che inveceArrayList
non possiede. -
Vector
ha svariati metodi “legacy” che inveceArrayList
non possiede:void addElement(E obj)
int capacity()
void copyInto(Object[] anArray)
E elementAt(int index)
Enumeration<E> elements()
E firstElement()
void insertElementAt(E obj, int index)
E lastElement()
void removeAllElements()
boolean removeElement(Object obj)
void removeElementAt(int index)
void setElementAt(E obj, int index)
void setSize(int newSize)
-
Vector
è in grado di fornire una enumeration (java.util.Enumeration
) mentreArrayList
non offre questa funzionalità. Inoltre, ilEnumeration
fornito daVector
non ha il comportamento fail-fast. -
Vector
è una classe thread-safe, tutti i suoi metodi sono “sincronizzati”, cioè la invocazione di uno qualunque dei suoi metodi acquisisce il monitor (lock) intrinseco dell’oggettoVector
per garantire la “mutua esclusione” tra thread.ArrayList
invece non è thread-safe e non offre alcun meccanismo di sincronizzazione. -
Le due collezioni differiscono nella logica impiegata per calcolare la nuova capacità da utilizzare per creare un array più “ampio”. In particolare, storicamente e fin dal principio,
Vector
ha sempre applicato un fattore di moltiplicazione di 2x mentreArrayList
ha sempre applicato un fattore di moltiplicazione di 1,5x rispetto alla capacità “corrente”.
NOTA: questo è un dettaglio implementativo (non documentato ufficialmente) che risulta ben noto dalla analisi dei sorgenti del framework nel JDK di Sun/Oracle. -
Vector
funge da classe “base” per la collezione chiamataStack
mentreArrayList
fa da classe “base” per alcune classi molto specializzate che fanno parte della API del management (packagejavax.management
).