wake-up-neo.com

Warum wird die Klasse Java Vector (und Stack) als veraltet oder veraltet betrachtet?

Warum wird Java Vector als veraltete oder veraltete Legacy-Klasse betrachtet?

Ist seine Verwendung nicht gültig, wenn Sie mit Parallelität arbeiten?

Und wenn ich keine Objekte manuell synchronisieren und nur eine thread-sichere Auflistung verwenden möchte, ohne dass neue Kopien des zugrunde liegenden Arrays erstellt werden müssen (wie dies bei CopyOnWriteArrayList der Fall ist), ist es dann in Ordnung, Vector zu verwenden?

Was ist mit Stack, einer Unterklasse von Vector? Was soll ich stattdessen verwenden?

653
fjsj

Vector wird bei jeder einzelnen Operation synchronisiert. Das ist fast nie das, was du machen willst.

Im Allgemeinen möchten Sie eine ganze Sequenz von Operationen synchronisieren. Das Synchronisieren einzelner Vorgänge ist sowohl weniger sicher (wenn Sie beispielsweise über einen Vector iterieren, müssen Sie immer noch eine Sperre aufheben, um zu verhindern, dass andere Personen gleichzeitig die Auflistung ändern, was zu einem ConcurrentModificationException im iterierenden Thread führen würde) als auch langsamer (warum ein Schloss mehrmals öffnen, wenn einmal ausreicht)?

Natürlich hat es auch den Overhead zu sperren, auch wenn Sie nicht brauchen.

Grundsätzlich ist es in den meisten Situationen ein sehr fehlerhafter Ansatz zur Synchronisation. Wie Herr Brian Henk betonte, können Sie eine Sammlung mit Aufrufen wie Collections.synchronizedList - der Tatsache dekorieren dass Vector sowohl die Implementierung der "Resized Array" -Auflistung als auch das "Synchronize Every Operation" -Bit kombiniert, ist ein weiteres Beispiel für schlechtes Design; Der Dekorationsansatz sorgt für eine sauberere Trennung der Anliegen.

Was ein Stack-Äquivalent betrifft, würde ich zunächst Deque/ArrayDeque betrachten.

634
Jon Skeet

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. Sie sollten also ArrayList heißen (das ist der Java 1.2 Collections-Ersatz für Vector).

2. Concurrency: Alle Methoden get(), set() sind synchronized, sodass Sie die Synchronisation nicht genau steuern können.

Es gibt keinen großen Unterschied zwischen ArrayList und Vector, aber Sie sollten ArrayList verwenden.

Aus dem API-Dokument.

Ab der Java 2-Plattform v1.2 wurde diese Klasse zur Implementierung der List-Schnittstelle nachgerüstet, sodass sie Mitglied des Java Collections Framework ist. Im Gegensatz zu den neuen Auflistungsimplementierungen wird Vector synchronisiert.

80
Justin

Neben den bereits erwähnten Antworten zur Verwendung von Vector bietet Vector auch eine Reihe von Methoden zum Aufzählen und Abrufen von Elementen, die sich von der List-Oberfläche unterscheiden, und Entwickler (insbesondere diejenigen, die Java vor 1.2 gelernt haben) können dazu neigen, diese zu verwenden sie, wenn sie im Code sind. Aufzählungen sind zwar schneller, sie überprüfen jedoch nicht, ob die Auflistung 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 und der damit verbundene Zugriff von mehreren Threads aus erfolgt, ist dies ein besonders gefährliches Problem. Durch die Verwendung dieser Methoden wird auch viel Code an Vector gekoppelt, sodass es nicht einfach ist, ihn durch eine andere List-Implementierung zu ersetzen.

41
Yishai

Sie können die synchronizedCollection/List -Methode für Java.util.Collection verwenden, um eine thread-sichere Auflistung von einer nicht thread-sicheren abzurufen.

14
Brian Henk

Java.util.Stack erbt den Synchronisationsaufwand von Java.util.Vector, der normalerweise nicht gerechtfertigt ist.

Es erbt jedoch noch viel mehr. Die Tatsache, dass Java.util.Stack extends Java.util.Vector ein Fehler im objektorientierten Design ist. Puristen werden feststellen, 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, search, elementAt, setElementAt, remove und viele andere Operationen mit wahlfreiem Zugriff auszuführen. Grundsätzlich ist es Sache des Benutzers, die Nicht-Stack-Operationen von Stack zu unterlassen.

Aus diesen Leistungs- und OOP Entwurfsgründen empfiehlt JavaDoc for Java.util.StackArrayDeque als natürlichen Ersatz. (Eine Deque ist mehr als ein Stapel, aber zumindest ist sie darauf beschränkt, die beiden Enden zu manipulieren, anstatt auf alles willkürlich zuzugreifen.)

6
200_success