Warum wird Java Vector als Legacy-Klasse angesehen, veraltet oder veraltet?
Ist seine Verwendung bei der Arbeit mit Parallelität nicht gültig?
Und wenn ich Objekte nicht manuell synchronisieren und nur eine thread-sichere Sammlung verwenden möchte, ohne (wie CopyOnWriteArrayList
auch) neue Kopien des zugrunde liegenden Arrays erstellen zu müssen, ist die Verwendung dann in Ordnung Vector
?
Was ist mit Stack
, was ist eine Unterklasse von Vector
, was soll ich stattdessen verwenden?
Antworten:
Vector
synchronisiert bei jeder einzelnen Operation. Das ist fast nie das, was du tun willst.Im Allgemeinen möchten Sie eine ganze Abfolge von Vorgängen synchronisieren . Das Synchronisieren einzelner Vorgänge ist sowohl weniger sicher (wenn Sie beispielsweise über eine iterieren
Vector
, müssen Sie dennoch eine Sperre aufheben, um zu vermeiden, dass andere Personen gleichzeitig die Sammlung ändern, was zu einemConcurrentModificationException
im iterierenden Thread führen würde) als auch langsamer ( Warum wiederholt ein Schloss schließen, wenn einmal genug ausreicht?Natürlich hat es auch den Aufwand, zu sperren, selbst wenn Sie nicht müssen.
Grundsätzlich ist es in den meisten Situationen ein sehr fehlerhafter Ansatz zur Synchronisation. Wie Herr Brian Henk betonte, können Sie eine Sammlung mithilfe folgender Aufrufe dekorieren
Collections.synchronizedList
: Die Tatsache, dassVector
sowohl die Implementierung der Sammlung "Resized Array" als auch das Bit "Jede Operation synchronisieren" kombiniert werden, ist ein weiteres Beispiel für schlechtes Design. Der Dekorationsansatz sorgt für eine sauberere Trennung der Anliegen.Was ein
Stack
Äquivalent betrifft - ich würde es mir ansehenDeque
/ArrayDeque
anfangen.quelle
Vector war Teil von 1.0 - die ursprüngliche Implementierung hatte zwei Nachteile:
1. Benennung: Vektoren sind eigentlich nur Listen, auf die als Arrays zugegriffen werden kann, daher sollte sie aufgerufen worden sein
ArrayList
(was der Ersatz für Java 1.2-Sammlungen istVector
).2. Concurrency: Alle die
get()
,set()
Methoden sindsynchronized
, so dass Sie nicht eine genaue Kontrolle über die Synchronisation gekörnt haben können.Es gibt keinen großen Unterschied zwischen
ArrayList
undVector
, aber Sie sollten verwendenArrayList
.Aus dem API-Dokument.
quelle
ArrayList
,LinkedList
etc., die alle die Schnittstelle implementierenList
, so dass , wenn Sie die nutzen wollenList
Methoden , ohne zu wissen , was die zugrunde liegende Implementierung Sie können tatsächlich nehmen nurList
als Parameter an Methoden usw. Das gleiche gilt für Implementierer gilt vonMap
und so weiter. Inzwischen hat C ++ einestd::array
Klasse, die nur ein vorlagenbasierter Ersatz für Arrays mit statischer Länge im C-Stil ist.Neben den bereits genannten Antworten zur Verwendung von Vector verfügt Vector auch über eine Reihe von Methoden zur Aufzählung und zum Abrufen von Elementen, die sich von der List-Oberfläche unterscheiden. Entwickler (insbesondere diejenigen, die Java vor 1.2 gelernt haben) können diese verwenden, wenn sie sich in der Code. Obwohl Aufzählungen schneller sind, prüfen sie nicht, ob die Sammlung während der Iteration geändert wurde, was zu Problemen führen kann. Angesichts der Tatsache, dass Vector möglicherweise für die Synchronisierung ausgewählt wurde, ist dies aufgrund des damit verbundenen Zugriffs von mehreren Threads ein besonders schädliches Problem. Durch die Verwendung dieser Methoden wird auch viel Code mit Vector gekoppelt, sodass es nicht einfach ist, ihn durch eine andere List-Implementierung zu ersetzen.
quelle
Sie können die synchronizedCollection / List- Methode in verwenden
java.util.Collection
, um eine thread-sichere Sammlung von einer nicht thread-sicheren Sammlung abzurufen.quelle
java.util.Stack
erbt den Synchronisationsaufwand vonjava.util.Vector
, der normalerweise nicht gerechtfertigt ist.Es erbt jedoch viel mehr als das. Die Tatsache, dass dies
java.util.Stack extends java.util.Vector
ein Fehler im objektorientierten Design ist. Puristen werden bemerken, dass es auch viele Methoden bietet, die über die traditionell mit einem Stapel verbundenen Operationen hinausgehen (nämlich: Push, Pop, Peek, Size). Es ist auch möglich zu tunsearch
,elementAt
,setElementAt
,remove
, und viele andere Schreib-Lese-Operationen. Grundsätzlich ist es Sache des Benutzers, die Nicht-Stack-Operationen von nicht zu verwendenStack
.Aus diesen Gründen der Leistung und des OOP-Designs empfiehlt JavaDoc
java.util.Stack
ArrayDeque
als natürlichen Ersatz. (Eine Deque ist mehr als ein Stapel, aber zumindest beschränkt sie sich darauf, die beiden Enden zu manipulieren, anstatt zufälligen Zugriff auf alles zu bieten.)quelle