ChatGPT解决这个技术问题 Extra ChatGPT

Why is Java Vector (and Stack) class considered obsolete or deprecated?

Why is Java Vector considered a legacy class, obsolete or deprecated?

Isn't its use valid when working with concurrency?

And if I don't want to manually synchronize objects and just want to use a thread-safe collection without needing to make fresh copies of the underlying array (as CopyOnWriteArrayList does), then is it fine to use Vector?

What about Stack, which is a subclass of Vector, what should I use instead of it?

They are obsolete, but they are not deprecated.

A
Am_I_Helpful

Vector synchronizes on each individual operation. That's almost never what you want to do.

Generally you want to synchronize a whole sequence of operations. Synchronizing individual operations is both less safe (if you iterate over a Vector, for instance, you still need to take out a lock to avoid anyone else changing the collection at the same time, which would cause a ConcurrentModificationException in the iterating thread) but also slower (why take out a lock repeatedly when once will be enough)?

Of course, it also has the overhead of locking even when you don't need to.

Basically, it's a very flawed approach to synchronization in most situations. As Mr Brian Henk pointed out, you can decorate a collection using the calls such as Collections.synchronizedList - the fact that Vector combines both the "resized array" collection implementation with the "synchronize every operation" bit is another example of poor design; the decoration approach gives cleaner separation of concerns.

As for a Stack equivalent - I'd look at Deque/ArrayDeque to start with.


"Generally you want to synchronize a whole sequence of operations." - That is the point! Thanks!
in which version of java Deprecated Vector (Currently i used Java7).But I never see as a Deprecated? Bye the Way nice Explanation ...+1
@Samir: It's not officially deprecated - it's just that ArrayList is generally preferred.
@Samir: No, I'm not going to try to predict the future.
@specializt: I think at this stage we'll have to agree to disagree.
r
roottraveller

Vector was part of 1.0 -- the original implementation had two drawbacks:

1. Naming: vectors are really just lists which can be accessed as arrays, so it should have been called ArrayList (which is the Java 1.2 Collections replacement for Vector).

2. Concurrency: All of the get(), set() methods are synchronized, so you can't have fine grained control over synchronization.

There is not much difference between ArrayList and Vector, but you should use ArrayList.

From the API doc.

As of the Java 2 platform v1.2, this class was retrofitted to implement the List interface, making it a member of the Java Collections Framework. Unlike the new collection implementations, Vector is synchronized.


Lists which can be accessed as arrays? ArrayList isn't a very short or catchy name, which might be why vector is used elsewhere (e.g. the STL).
@dhardy List with an array as its underlying implementation. There's ArrayList, LinkedList, etc., all of which implement the interface List, so if you want to utilize the List methods without having to know what the underlying implementation actually is you can just take a List as a parameter to methods, etc. The same applies for implementers of Map and so on. Meanwhile, C++ does have a std::array class, which is just a template-based replacement for C-style static length arrays.
Y
Yishai

Besides the already stated answers about using Vector, Vector also has a bunch of methods around enumeration and element retrieval which are different than the List interface, and developers (especially those who learned Java before 1.2) can tend to use them if they are in the code. Although Enumerations are faster, they don't check if the collection was modified during iteration, which can cause issues, and given that Vector might be chosen for its syncronization - with the attendant access from multiple threads, this makes it a particularly pernicious problem. Usage of these methods also couples a lot of code to Vector, such that it won't be easy to replace it with a different List implementation.


N
Nubok

You can use the synchronizedCollection/List method in java.util.Collection to get a thread-safe collection from a non-thread-safe one.


why this is better than vector?
As Jon mentioned, Vector will not perform as well, and this method allows you to choose when its a good idea to do the synchronization. Its totally a design issue. You should use ArrayList over Vector because you should default to non-synchronized access.
How does this answer the question?
2
200_success

java.util.Stack inherits the synchronization overhead of java.util.Vector, which is usually not justified.

It inherits a lot more than that, though. The fact that java.util.Stack extends java.util.Vector is a mistake in object-oriented design. Purists will note that it also offers a lot of methods beyond the operations traditionally associated with a stack (namely: push, pop, peek, size). It's also possible to do search, elementAt, setElementAt, remove, and many other random-access operations. It's basically up to the user to refrain from using the non-stack operations of Stack.

For these performance and OOP design reasons, the JavaDoc for java.util.Stack recommends ArrayDeque as the natural replacement. (A deque is more than a stack, but at least it's restricted to manipulating the two ends, rather than offering random access to everything.)