为什么Java Vector类被认为已经过时或被弃用?
为什么Java向量被认为是遗留类,已经过时或被弃用?
使用并发时,它的使用是否有效?
如果我不想手动同步对象,只想使用线程安全的集合,而不需要创build底层数组的新副本(就像CopyOnWriteArrayList
那样),那么使用Vector
吗?
怎么样Stack
,这是Vector
一个子类,我应该用什么来代替它呢?
Vector
在每个单独的操作上同步。 这几乎从来不是你想要做的。
通常你想同步整个操作序列 。 同步单个操作不太安全(例如,如果遍历Vector
,则仍然需要取出一个锁以避免其他人同时更改集合,这会在迭代线程中导致ConcurrentModificationException
),但同时慢一点(为什么要重复一次锁就足够了)?
当然,即使你不需要,它也有locking的开销。
基本上,在大多数情况下,这是一个非常有缺陷的同步方法。 正如Brian Henk先生所指出的那样,您可以使用诸如Collections.synchronizedList
之类的调用来装饰一个集合 – Vector
将“resize的数组”集合实现与“同步每个操作”位相结合的事实是devise不佳的另一个例子; 装饰方式让人更清楚的分离关注点。
至于Stack
等价物 – 我会看看Deque
/ ArrayDeque
开始。
向量是1.0的一部分 – 原来的实现有两个缺点:
1.命名:向量实际上只是可以作为数组访问的列表,所以它应该被称为ArrayList
(这是Java 1.2集合的Vector
replace)。
2.并发性:所有的get()
, set()
方法都是synchronized
,所以你不能对同步进行细粒度的控制。
ArrayList
和Vector
没有太大的区别,但是你应该使用ArrayList
。
从API文档。
从Java 2平台v1.2开始,这个类被改进以实现List接口,使其成为Java Collections Framework的成员。 与新的集合实现不同,Vector是同步的。
除了已经提到的有关使用Vector的答案之外,Vector还有一些与List接口不同的枚举和元素检索方法,开发人员(尤其是那些在1.2之前学过Java的人)可以倾向于使用它们码。 虽然枚举速度更快,但它们并不检查集合是否在迭代期间被修改,这可能会导致问题,并且鉴于可能selectVector作为其同步操作 – 随同从多个线程访问,这使得它成为一个特别有害的问题。 这些方法的使用还会将很多代码耦合到Vector中,以便用不同的List实现来replace它。
您可以使用java.util.Collection
上的synchronizedCollection / List方法从非线程安全的集合java.util.Collection
获取线程安全的集合。
java.util.Stack
inheritancejava.util.Stack
的同步开销,这通常是不合理的。
不过,它inheritance了更多的东西。 java.util.Stack extends java.util.Vector
的事实在面向对象devisejava.util.Stack extends java.util.Vector
是一个错误。 纯粹主义者会注意到,它还提供了超越传统上与堆栈相关的操作(即:push,pop,peek,size)的很多方法。 也可以执行search
, elementAt
, setElementAt
, remove
和其他许多随机访问操作。 基本上由用户决定不使用Stack
的非堆栈操作。
对于这些性能和OOPdevise原因, JavaDoc for java.util.Stack
build议将ArrayDeque
作为自然替代品。 (Deque不仅仅是一个堆栈,但至less它只能操纵两端,而不是随机访问所有东西。)