DOMANDA [JAVA] Differenze tra ArrayList e Vector

Pubblicità

Alessandro001

Utente Attivo
Messaggi
166
Reazioni
7
Punteggio
44
Salve, oltre alle differenze citate di seguito tra ArrayList e Vector quali altre sostanziali differenze ci sono tra le due classi? E cosa si intende per metodi sincronizzati? Inoltre ho notato che i metodi della classe ArrayList sono quasi tutti contenuti nella classe Vector...

1) I metodi di Vector sono sincronizzati, mentre quelli di ArrayList non lo sono.
2) Vector fornisce, con metodi e costruttori, un controllo maggiore sulla capacità, e sulla dimensione dell'array.
 
Il punto fondamentale è il primo. Vector è sincronizzato, quindi è da usare con il multithreading.

Se non erro anche l'implementazione interna è uguale nel modo in cui gli elementi vengono allocati, ma in questo potrei errare.
 
Il punto fondamentale è il primo. Vector è sincronizzato, quindi è da usare con il multithreading.

Se non erro anche l'implementazione interna è uguale nel modo in cui gli elementi vengono allocati, ma in questo potrei errare.
Guarda io avevo un programma gestito totalmente con l'ArrayList e cambiando ArrayList con Vector funziona perfettamente tutto ed anche meglio perchè la size non viene moltiplicata ogni volta ma dal costruttore di Vector scelgo io di quanto incrementare ogni volta...
Comunque non mi è molto chiaro il primo punto non avendo molta esperienza della programmazione Java in multithreading ...
 
Il primo punto è quello chiave: se non ci sono più thread che usano la stessa struttura dati, l'ArrayList ha prestazioni superiori rispetto a Vector perché non implementa nessun controllo di sincronizzazione. Il funzionamento interno invece è quasi identico, alla fin fine sono entrambi degli array ridimensionabili e differiscono solo per il fattore di crescita auotmatica (se non ricordo male il vector raddoppia le dimensioni quando esarurisce lo spazio inizialmente allocato, invece l'ArrayList le incrementa del 50%)
 
Tieni presente che estendono la stessa classe e implementano le stesse interfaccie (giusto per far notare che sono uguali).
Si, con Vector il costruttore permette di specificare anche l'incremento quando il limite viene raggiunto.

La differenza è molto importante (mentre scrivevo ho notato la risposta di BAT, che sottoscrivo): nel caso di multithreading con Java puoi evitare che un blocco di codice, o un metodo, venga acceduto da più di 1 thread alla volta; per far ciò si utilizza la parola chiave synchronized.

Per fare un esempio, questa l'implementazione di add() di Vector:

Java:
    public synchronized boolean add(E e) {
        modCount++;
        ensureCapacityHelper(elementCount + 1);
        elementData[elementCount++] = e;
        return true;
    }

Questo è invece quello di ArrayList:
Java:
    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

utilizzando i metodi sincronizzati, o in generale sincronizzando una parte del codice, si è sicuri che solo 1 thread acceda ad una risorsa.
Se non utilizzi Vector devi gestire tu stesso questi aspetti.

La capacità cresce - guardando il sorgente - in questo modo per Vector (non riporto il controllo sul numero < 0 o superiore alla capacità massima per semplicità):
Java:
int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity);

e questo è quello di ArrayList:
Java:
int newCapacity = oldCapacity + (oldCapacity >> 1);

quindi la dimensione di ArrayList, come dice BAT, cresce del 50% (oldCapacity >> 1, equivale a oldCapacity / 2), mentre quella di Vector del 100% se non viene specificato il parametro capacityIncrement (quello che citavi tu inizialmente).

Insomma, in pratica: senza multithreading ti converrebbe ArrayList. Se lo trovi lento probabilmente dipende dalla quantità di allocazioni: hai tanti elementi da memorizzare, e raggiungi velocemente quel 50% in più che viene allocato da ArrayList; questo provoca ovviamente un maggior numero di allocazioni.
Oppure, il parametro che tu passi a Vector è maggiore al 50% di ArrayList, quindi allochi più memoria, ma fai meno allocazioni ("sprecandone" di più).

Per il resto anche se guardi i sorgenti noterai le similitudini (li trovi zippati nella cartella del JDK).
 
Tieni presente che estendono la stessa classe e implementano le stesse interfaccie (giusto per far notare che sono uguali).
Si, con Vector il costruttore permette di specificare anche l'incremento quando il limite viene raggiunto.

La differenza è molto importante (mentre scrivevo ho notato la risposta di BAT, che sottoscrivo): nel caso di multithreading con Java puoi evitare che un blocco di codice, o un metodo, venga acceduto da più di 1 thread alla volta; per far ciò si utilizza la parola chiave synchronized.

Per fare un esempio, questa l'implementazione di add() di Vector:

Java:
public synchronized boolean add(E e) {
modCount++;
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = e;
return true;
}

Questo è invece quello di ArrayList:
Java:
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}

utilizzando i metodi sincronizzati, o in generale sincronizzando una parte del codice, si è sicuri che solo 1 thread acceda ad una risorsa.
Se non utilizzi Vector devi gestire tu stesso questi aspetti.

La capacità cresce - guardando il sorgente - in questo modo per Vector (non riporto il controllo sul numero < 0 o superiore alla capacità massima per semplicità):
Java:
int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity);

e questo è quello di ArrayList:
Java:
int newCapacity = oldCapacity + (oldCapacity >> 1);

quindi la dimensione di ArrayList, come dice BAT, cresce del 50% (oldCapacity >> 1, equivale a oldCapacity / 2), mentre quella di Vector del 100% se non viene specificato il parametro capacityIncrement (quello che citavi tu inizialmente).

Insomma, in pratica: senza multithreading ti converrebbe ArrayList. Se lo trovi lento probabilmente dipende dalla quantità di allocazioni: hai tanti elementi da memorizzare, e raggiungi velocemente quel 50% in più che viene allocato da ArrayList; questo provoca ovviamente un maggior numero di allocazioni.
Oppure, il parametro che tu passi a Vector è maggiore al 50% di ArrayList, quindi allochi più memoria, ma fai meno allocazioni ("sprecandone" di più).

Per il resto anche se guardi i sorgenti noterai le similitudini (li trovi zippati nella cartella del JDK).
Davvero ottime risposte le vostre.
Ho capito tutto e vi ringrazio!

Inviato da SNE-LX1 tramite App ufficiale di Tom\'s Hardware Italia Forum
 
Pubblicità
Pubblicità
Indietro
Top