738

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?

Patrick Parker
  • 4,863
  • 4
  • 19
  • 51
fjsj
  • 10,995
  • 11
  • 41
  • 57

5 Answers5

711

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.

Am_I_Helpful
  • 18,735
  • 7
  • 49
  • 73
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 125
    "Generally you want to synchronize a whole sequence of operations." - That is the point! Thanks! – fjsj Sep 07 '09 at 00:56
  • 7
    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 Mangroliya Mar 09 '12 at 16:55
  • 19
    @Samir: It's not officially deprecated - it's just that ArrayList is generally preferred. – Jon Skeet Mar 09 '12 at 17:04
  • can you tell me, in Future it happens ? – Samir Mangroliya Mar 09 '12 at 17:06
  • 31
    @Samir: No, I'm not going to try to predict the future. – Jon Skeet Mar 09 '12 at 17:11
  • 2
    @Jon Thanks for the explanation. One minor correction - the statement "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" is only partially correct - the iterator will throw a ConcurrentModificationException to avoid unpredictable behaviour if this occurs. – Alex May 05 '13 at 05:58
  • 2
    @Alex: Well, my point was that you synchronize to avoid the consequences of another thread trying to do so. Will clarify. – Jon Skeet May 05 '13 at 06:06
  • 2
    @Alex: The iterator will *try* to throw an exception. It's not guaranteed, though. The docs basically say "it's just to help detect bugs. Don't rely on it." – cHao May 07 '13 at 01:18
  • 5
    simply gr8. vector is not deprecated its a legacy class.There must be difference between deprecated and legacy and yes there is see http://stackoverflow.com/questions/2873254/difference-between-a-deprecated-and-a-legacy-api – Prashant Shilimkar Dec 23 '13 at 06:23
  • 2
    Is there any situation where we actually need Vector to be used?? – Raja Asthana Apr 03 '14 at 07:20
  • @RajaAsthana: Well you might be interoperating with another API which uses it. I can't remember the last time I saw it in fresh code though. – Jon Skeet Apr 03 '14 at 07:22
  • I do see a lot of code especially while adding errors like errorVector.add("invalid name"). Do we need to avoid this? – Raja Asthana Apr 03 '14 at 07:33
  • @RajaAsthana: That really depends on the context. Where do you see all this code? Is it within some legacy codebase? – Jon Skeet Apr 03 '14 at 08:20
  • @RajaAsthana: Then that's why you're seeing it, basically. – Jon Skeet Apr 03 '14 at 09:40
  • @JonSkeet Last time I see Vector in code is in some example code in "Beginning JSP, JSF and Tomcat" Copyright © 2012 by Giulio Zambon. I am reading it right now. Now, after reading your post I wonder why is he still using it? Especially as he instructs at beginning of the book installing Java 7 SDK (and Tomcat 7). As for code itself he is using it because of synchronization... – Nenad Bulatović Jun 18 '14 at 05:11
  • 3
    @Nenad: I can't really answer that - but it's not what I'd do if I were writing such a book. – Jon Skeet Jun 18 '14 at 05:21
  • Vector has the advantage of a short catchy name and its entrenchment in C++, which many programmers started out with. Outside of (inefficient) built in synchronization with Vector, you should be able to do anything with ArrayList you could do with Vector, and generally do it faster. – Androidcoder Apr 11 '15 at 15:26
  • 2
    i never understood why there are people who call some parts of some API "dead" or "legacy" just because it might be inefficient. NEWSFLASH : almost all algorithms out there can be optimized, quite a lot are inefficient - yet noone calls it "dead". Efficiency isnt important anymore, we are in the 21st century so unless you're writing high-performance embedded software for space-shuttles (well, the successor) there is no point in ranting against API like that -- and even then : *software engineers* simply choose some alternative, they dont rant but dont worry about that just yet :) – specializt Feb 10 '16 at 06:37
  • 5
    @specializt: I think it's entirely reasonable to call it a legacy API if there's an alternative which is clearly better in most situations. Not only is `Vector` less efficient in terms of synchronizing unnecessarily, but by doing that synchronization it can give the *illusion* of being thread-safe to users who are new to threading and think that synchronizing each operation is sufficient to make it safe to use arbitrarily across threads. I'm still very happy to recommend moving from `Vector` to `ArrayList` in almost all cases. – Jon Skeet Feb 10 '16 at 06:50
  • 1
    that doesnt make any sense -- its reasonable to call something "legacy" if there are **better alternatives**? You might want to think about that again .... with that reasoning pretty much anything in existence is "legacy" – specializt Feb 10 '16 at 06:51
  • 2
    @specializt: Nope, I don't think so. Searching for "define:legacy", the relevant adjective for computing states: "denoting or relating to software or hardware that has been superseded but is difficult to replace because of its wide use." That sounds pretty similar to what I said. Note that "better in most situations" is a pretty high bar - while `LinkedList` is better than `ArrayList` in *some* situations, the reverse is often true - neither effectively deprecates the other. – Jon Skeet Feb 10 '16 at 06:58
  • @specializt: Also, from the JLS 9.6.4.6: "A program element annotated @Deprecated is one that programmers are discouraged from using, typically because it is dangerous, or because a better alternative exists." (Yes I'm aware that deprecated and legacy are not the same word, but they're often used somewhat-synonymously here. Not that `Vector` is officially deprecated, mind you... just like `Date` and `Calendar` aren't, but I wouldn't want to use those in new development either.) – Jon Skeet Feb 10 '16 at 06:59
  • .. so it also is deprecated because you dont want to use it. Roight. – specializt Feb 10 '16 at 07:01
  • 6
    @specializt: I think at this stage we'll have to agree to disagree. – Jon Skeet Feb 10 '16 at 07:02
  • For concurrency concern we can use java Concurrent package. However we can write code which access the collection in a non Thread-Safe manner. – Hamedz Jun 08 '16 at 18:20
  • @Jon Thanks for the good answer. "As for a `Stack` equivalent - I'd look at `Deque`/`ArrayDeque` to start with." Does `Stack` also have synchronized methods as its superclass `Vector`? Should we replace `Stack` with `Collections.synchronizedList` applying to `Deque/ArrayDeque`? –  Nov 21 '17 at 18:50
  • @Ben: I'd expect any calls in `Stack` to go via the superclass methods anyway, but I'd have to check to be sure. – Jon Skeet Nov 21 '17 at 21:48
  • @specializt "Efficiency isnt important anymore". If efficiency were unimportant for lower-level programmers, it could't be unimportant for high-level productivity boys. – Dávid Horváth Sep 12 '20 at 15:46
  • yet again : that doesnt seem to make any sense. Efficiency isnt important for **anyone** anymore ... well ... maybe except for realtime-devs which work at projects for products which endanger **or** save human lives, probably - but thats a pretty small subgroup of people. Shaving off a few CPU cycles is a thing of the distant past - get over it already. Yes, we all know that you **love** to do it but it simply is unneccessary for product development; you can insert an optimization iteration after release if you're so desperate to make it faster. – specializt Sep 19 '20 at 20:01
  • @specializt It can be unimportant in the higher levels. If you develop a REST service over a database in Spring, then it can be unimportant. But, if you develop Spring or Hibernate itself, or the underlying JDBC driver, or the RDBMS itself or the OS kernel under all, then not. And, even in higher level, today’s man can’t tolerate even a tiny interruption in his/her most used apps. Performance matters. – Dávid Horváth Oct 07 '20 at 23:00
  • I think you fail to understand the difference between "interruptions" to UX and (background) performance - both need not (in fact : must not) be connected - very slow background / threaded algorithms dont have *any* effect on UX - hence don't matter performance-wise. Unless, of course your developers are highly inexperienced and cannot (or will not) decouple UI/UX from logic. Dont worry : you'll discover that yourself in the next fee years – specializt Oct 15 '20 at 04:19
  • @specializt I can't understand you. How does badly implemented concurrency and UI interruptions come here? Freezing UI graphics or slow package dependency resolution can be annoying, on their own. Anyhow, we should stop or move to the chat. – Dávid Horváth Dec 25 '20 at 05:23
  • i think you should re-do some sort of beginner-level course about programming, including concurrency and UI threads / main threads ... and maybe lookup the term "dependency resolution", you seem to mix up quite a few things here. – specializt Jan 01 '21 at 06:32
91

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.

roottraveller
  • 7,942
  • 7
  • 60
  • 65
Justin
  • 4,437
  • 6
  • 32
  • 52
  • 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 May 06 '13 at 14:48
  • 6
    @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. – JAB May 14 '14 at 15:07
43

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.

Yishai
  • 90,445
  • 31
  • 189
  • 263
15

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

Nubok
  • 3,502
  • 7
  • 27
  • 47
Brian Henk
  • 623
  • 1
  • 6
  • 14
  • 4
    why this is better than vector? – fjsj Sep 06 '09 at 18:13
  • 8
    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. – Brian Henk Sep 06 '09 at 18:22
  • How does this answer the question? – user207421 Apr 08 '19 at 08:17
14

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.)

200_success
  • 7,286
  • 1
  • 43
  • 74