为什么 Java Vector(和 Stack)类被认为已过时或已弃用?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1386275/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 11:28:59  来源:igfitidea点击:

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

javavectorstackdeprecatedobsolete

提问by fjsj

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

为什么 Java Vector 被视为遗留类、已过时或已弃用?

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 CopyOnWriteArrayListdoes), then is it fine to use Vector?

如果我不想手动同步对象而只想使用线程安全集合而不需要制作底层数组的新副本(就像CopyOnWriteArrayList那样),那么可以使用Vector吗?

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

怎么样Stack,它是 的子类Vector,我应该用什么来代替它?

采纳答案by Jon Skeet

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

Vector在每个单独的操作上同步。这几乎从来都不是你想做的。

Generally you want to synchronize a whole sequenceof 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 ConcurrentModificationExceptionin the iterating thread) but also slower (why take out a lock repeatedly when once will be enough)?

通常,您希望同步整个操作序列。同步单个操作既不太安全(Vector例如,如果您迭代 a ,您仍然需要取出锁以避免其他人同时更改集合,这会导致ConcurrentModificationException迭代线程中的 a )而且速度较慢(为什么一次就足够了,为什么要反复取出锁)?

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 Henkpointed out, you can decorate a collection using the calls such as Collections.synchronizedList- the fact that Vectorcombines 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.

基本上,在大多数情况下,这是一种非常有缺陷的同步方法。正如Brian Henk 先生指出的那样,您可以使用以下调用来装饰集合Collections.synchronizedList-Vector将“调整大小的数组”集合实现与“同步每个操作”位相结合的事实是另一个糟糕设计的例子;装饰方法提供了更清晰的关注点分离。

As for a Stackequivalent - I'd look at Deque/ArrayDequeto start with.

至于Stack等价物 - 我会先看Deque/ ArrayDeque

回答by Brian Henk

You can use the synchronizedCollection/Listmethod in java.util.Collectionto get a thread-safe collection from a non-thread-safe one.

您可以使用synchronizedCollection/List方法java.util.Collection从非线程安全集合中获取线程安全集合。

回答by Justin

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

Vector 是 1.0 的一部分——最初的实现有两个缺点:

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

1. 命名:向量实际上只是可以作为数组访问的列表,因此应该调用它ArrayList(这是 Java 1.2 Collections 的替代品Vector)。

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

2. 并发:所有的get(),set()方法都是synchronized,所以你不能对同步进行细粒度的控制。

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

ArrayList和之间没有太大区别Vector,但您应该使用ArrayList.

From the API doc.

来自 API 文档。

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.

从 Java 2 平台 v1.2 开始,该类经过改造以实现 List 接口,使其成为 Java Collections Framework 的成员。与新的集合实现不同,Vector 是同步的。

回答by 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.

除了已经说明的关于使用 Vector 的答案外,Vector 还有一堆枚举和元素检索方法,这些方法与 List 接口不同,开发人员(尤其是那些在 1.2 之前学习过 Java 的开发人员)如果在代码。尽管枚举速度更快,但它们不会检查集合是否在迭代期间被修改,这可能会导致问题,并且考虑到可能会选择 Vector 进行同步 - 伴随着来自多个线程的访问,这使其成为一个特别有害的问题。使用这些方法还会将大量代码耦合到 Vector,因此用不同的 List 实现替换它并不容易。

回答by 200_success

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

java.util.Stack继承了 的同步开销java.util.Vector,这通常是不合理的。

It inherits a lot more than that, though. The fact that java.util.Stack extends java.util.Vectoris 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.

不过,它继承的远不止这些。事实上,这java.util.Stack extends java.util.Vector是面向对象设计中的一个错误。纯粹主义者会注意到,除了传统上与堆栈相关的操作(即:push、pop、peek、size)之外,它还提供了许多方法。它也可以做到searchelementAtsetElementAtremove,和其他许多随机存取操作。基本上由用户决定不使用Stack.

For these performance and OOP design reasons, the JavaDoc for java.util.Stackrecommends ArrayDequeas 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.)

由于这些性能和 OOP 设计原因,JavaDoc forjava.util.Stack推荐ArrayDeque作为自然的替代品。(双端队列不仅仅是一个堆栈,但至少它仅限于操作两端,而不是提供对所有内容的随机访问。)