Perché la classe Java Vector (e Stack) è considerata obsoleta o deprecata?


677

Perché Java Vector è considerato una classe legacy, obsoleta o deprecata?

Il suo uso non è valido quando si lavora con la concorrenza?

E se non voglio sincronizzare manualmente gli oggetti e voglio solo usare una raccolta thread-safe senza dover fare nuove copie dell'array sottostante (come CopyOnWriteArrayListfa), allora va bene usare Vector?

Che dire Stack, che è una sottoclasse di Vector, cosa dovrei usare al posto di essa?


Sono obsoleti, ma non sono deprecati.
Marchese di Lorne,

Risposte:


655

Vectorsi sincronizza su ogni singola operazione. Non è quasi mai quello che vuoi fare.

Generalmente si desidera sincronizzare un'intera sequenza di operazioni. Sincronizzare le singole operazioni è sia meno sicuro (se si iterera su un Vector, ad esempio, è ancora necessario rimuovere un blocco per evitare che qualcun altro cambi la raccolta allo stesso tempo, il che causerebbe un ConcurrentModificationExceptionerrore nel thread iterante) ma anche più lento ( perché estrarre ripetutamente un lucchetto quando sarà sufficiente)?

Certo, ha anche il sovraccarico del blocco anche quando non è necessario.

Fondamentalmente, è un approccio molto imperfetto alla sincronizzazione nella maggior parte delle situazioni. Come ha sottolineato l' onorevole Brian Henk , è possibile decorare una collezione usando le seguenti chiamate Collections.synchronizedList: il fatto che Vectorcombina l'implementazione della raccolta "array ridimensionato" con il bit "sincronizza ogni operazione" è un altro esempio di design scadente; l'approccio decorativo offre una separazione più chiara delle preoccupazioni.

Per quanto riguarda un Stackequivalente - guarderei Deque/ ArrayDequeper cominciare.


108
"In genere si desidera sincronizzare un'intera sequenza di operazioni." - Questo è il punto! Grazie!
fjsj,

7
in quale versione di java Deprecated Vector (attualmente ho usato Java7). Ma non lo vedo mai come obsoleto? Ciao, bella spiegazione ... + 1
Samir Mangroliya

17
@Samir: non è ufficialmente deprecato - è solo che ArrayList è generalmente preferito.
Jon Skeet,

26
@ Samir: No, non proverò a prevedere il futuro.
Jon Skeet

5
semplicemente gr8. vettore non è deprecato la sua eredità class.There deve essere differenza tra deprecato e legacy e sì, c'è vedere stackoverflow.com/questions/2873254/...
Prashant Shilimkar

82

Vector faceva parte della 1.0: l'implementazione originale presentava due inconvenienti:

1. Denominazione: i vettori sono in realtà solo elenchi a cui è possibile accedere come array, quindi avrebbe dovuto essere chiamato ArrayList(che è il sostituto delle raccolte Java 1.2 per Vector).

2. Concurrency: Tutti i get(), set()metodi sono synchronized, quindi non si può avere a grana fine il controllo sulla sincronizzazione.

Non c'è molta differenza tra ArrayListe Vector, ma dovresti usare ArrayList.

Dal documento API.

A partire dalla piattaforma Java 2 v1.2, questa classe è stata adattata per implementare l'interfaccia List, rendendola membro del Java Collections Framework. A differenza delle nuove implementazioni di raccolta, Vector è sincronizzato.


Elenchi a cui è possibile accedere come array? ArrayList non è un nome molto breve o accattivante, il che potrebbe essere il motivo per cui il vettore viene utilizzato altrove (ad es. STL).
dhardy,

6
@dhardy Elenco con un array come implementazione sottostante. Ci sono ArrayList, LinkedListecc., Tutti i quali implementano l'interfaccia List, quindi se si desidera utilizzare i Listmetodi senza dover sapere quale sia effettivamente l'implementazione sottostante, si può semplicemente prendere Listun parametro per i metodi, ecc. Lo stesso vale per gli implementatori di Mape così via. Nel frattempo, C ++ ha una std::arrayclasse, che è solo una sostituzione basata su template per matrici di lunghezza statica in stile C.
JAB

41

Oltre alle risposte già dichiarate sull'uso di Vector, Vector ha anche un sacco di metodi di enumerazione e recupero degli elementi che sono diversi dall'interfaccia Elenco e gli sviluppatori (specialmente quelli che hanno imparato Java prima della 1.2) possono tendere ad usarli se si trovano nella codice. Sebbene le enumerazioni siano più veloci, non controllano se la raccolta è stata modificata durante l'iterazione, il che può causare problemi e dato che Vector potrebbe essere scelto per la sua sincronizzazione - con l'accesso dell'operatore da più thread, questo lo rende un problema particolarmente pernicioso. L'uso di questi metodi associa anche molto codice a Vector, in modo tale che non sarà facile sostituirlo con un'implementazione dell'elenco diversa.


14

È possibile utilizzare il metodo synchronizedCollection / Listjava.util.Collection per ottenere una raccolta thread-safe da una raccolta non thread-safe.


2
perché questo è meglio del vettore?
fjsj,

8
Come menzionato da Jon, Vector non funzionerà altrettanto bene e questo metodo ti consente di scegliere quando è una buona idea eseguire la sincronizzazione. È totalmente un problema di progettazione. Dovresti usare ArrayList su Vector perché dovresti avere un accesso predefinito non sincronizzato.
Brian Henk,

Come risponde alla domanda?
Marchese di Lorne,

8

java.util.Stack eredita l'overhead di sincronizzazione di java.util.Vector , che di solito non è giustificato.

Tuttavia, eredita molto di più. Il fatto java.util.Stack extends java.util.Vectorè un errore nella progettazione orientata agli oggetti. I puristi noteranno che offre anche molti metodi oltre alle operazioni tradizionalmente associate a uno stack (vale a dire: push, pop, peek, size). E 'anche possibile fare search, elementAt, setElementAt, remove, e molte altre operazioni ad accesso casuale. In pratica spetta all'utente astenersi dall'utilizzare le operazioni non stack diStack .

Per questi motivi di prestazioni e design OOP, JavaDocjava.util.Stack consiglia ArrayDequecome sostituto naturale. (Un deque è più di uno stack, ma almeno è limitato alla manipolazione delle due estremità, piuttosto che offrire un accesso casuale a tutto.)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.