Vector和ArrayList区别
要回答这个问题不能一概而论,有时候使用Vector比较好;有时是ArrayList,有时候这两个都不是2 o+ S' Z( o n6 u5 \- n+ P& }
* E) Y% Z9 M0 N+ g. n- ~7 z, t最好的选择。你别指望能够获得一个简单肯定答案,因为这要看你用它们干什么。下面有4个要考虑
; w+ K9 k% @9 z9 C4 K3 \- d$ F$ o+ f. z0 w' ?
的因素:( H2 Q' |5 l' T3 z* I
API
# [3 W* | R8 n Q2 C. W
2 S5 q* G2 r( x3 V
) o* R( m' _* j/ k2 |4 f2 S在由Ken Arnold等编著的《Java Programming Language》(Addison-Wesley, June 2000)一书中有这
$ B! e8 x0 @/ j6 f* F" G1 G' V( T3 m+ L8 Y3 A! }3 ~& Q' y
样的描述,Vector类似于ArrayList.。所有从API的角度来看这两个类非常相似。但他们之间也还
7 Z+ [$ _; Z7 v+ r! Z* F3 A: e1 y; X3 [" a+ k- x' Y2 n2 A$ z
是有一些主要的区别的。
, ^+ d% g9 D* K8 r; y* N9 U- @/ E `/ _: C% T3 x: [/ W% ?
同步性
. Q/ A4 m, ^" ]% C$ ]% L" |9 l7 a8 v Z5 R b, A
( L; K/ j P2 S& Z# {0 C& V- v
Vector是同步的。这个类中的一些方法保证了Vector中的对象是线程安全的。而ArrayList则是异步
' t. S' c) x: H5 x
3 h+ R7 m/ x2 \; L$ ]) o, v的,因此ArrayList中的对象并不是线程安全的。因为同步的要求会影响执行的效率,所以如果你不
( ~6 z5 H7 V. k3 o% G, M) C& R3 ?5 U& Y
需要线程安全的集合那么使用ArrayList是一个很好的选择,这样可以避免由于同步带来的不必要的
, d' O& w1 ?) Z# S7 J9 ~ n S& g; l, _. q5 j. n" {
性能开销。
9 X4 ?! x1 S$ L: _7 S# u/ N* q- Z2 v$ \' |
4 i4 h. B% p7 ?
数据增长
7 g, u5 J) q U$ b" X
" R2 r4 z) Q0 @1 U1 v$ {+ P" |' d2 A- d$ F8 J" [
从内部实现机制来讲ArrayList和Vector都是使用数组(Array)来控制集合中的对象。当你向这两种类$ ^, F2 J/ N2 ~' U: M& R
- H1 m% k- I* R' Z6 E型中增加元素的时候,如果元素的数目超出了内部数组目前的长度它们都需要扩展内部数组的长度,
% M' N' ]1 g" `/ A5 L$ D
7 E0 B6 d/ p) _+ x! ZVector缺省情况下自动增长原来一倍的数组长度,ArrayList是原来的50%,所以最后你获得的这个集8 g, n( `# ]( l$ {& b
* F1 B4 c, h w/ h$ @
合所占的空间总是比你实际需要的要大。所以如果你要在集合中保存大量的数据那么使用Vector有一/ `% G' M* z' i; k* h
% C, ]) {# @" z5 F9 C+ s% E
些优势,因为你可以通过设置集合的初始化大小来避免不必要的资源开销。
. Z2 u. {2 x) @! V, O4 O) S
' F0 r% z; E! M" v8 a" i6 n: N
% \& W" C$ u, q6 N8 @9 E使用模式
: N/ v8 B; a% [, h* Y0 }, m6 \ E, V y
x; C1 R' H6 O7 @" x
在ArrayList和Vector中,从一个指定的位置(通过索引)查找数据或是在集合的末尾增加、移除一
9 T Z& k8 g* m
' b y" O8 P& @5 z( h" C$ O% f个元素所花费的时间是一样的,这个时间我们用O(1)表示。但是,如果在集合的其他位置增加或移除3 r+ i, X1 G* r1 f1 b! h, g
3 q8 ]+ r4 `9 k r; r
元素那么花费的时间会呈线形增长:O(n-i),其中n代表集合中元素的个数,i代表元素增加或移除元
' ?3 o q9 t! W# {# A3 s1 u% X, Q# ~. d6 N) J& g
素的索引位置。为什么会这样呢?以为在进行上述操作的时候集合中第i和第i个元素之后的所有元素
8 ^4 f# G4 \4 u% R. V* b/ ^9 h8 B) i P: _4 N
都要执行位移的操作。这一切意味着什么呢?
# X( b/ j+ c" B6 @6 M! Z G+ P! B \$ \( g( @* E% b& `
) p7 d$ v+ b! A& u这意味着,你只是查找特定位置的元素或只在集合的末端增加、移除元素,那么使用Vector或
; W! S9 ?/ e( o2 e$ L! z0 X5 n) c; a+ p4 k
ArrayList都可以。如果是其他操作,你最好选择其他的集合操作类。比如,LinkList集合类在增加
" `* ~. l E) ^2 m$ \ J* B5 H, l: l9 V" y4 _9 f9 s
或移除集合中任何位置的元素所花费的时间都是一样的?O(1),但它在索引一个元素的使用缺比较慢8 z, x3 k" N/ m
" _! l a( ?" Y3 }
-O(i),其中i是索引的位置.使用ArrayList也很容易,因为你可以简单的使用索引来代替创建
3 k6 p7 F- j1 G8 S$ L" \( q! K8 V' @, m4 P* E
iterator对象的操作。LinkList也会为每个插入的元素创建对象,所有你要明白它也会带来额外的开
8 ]* `5 I7 Z& v1 T/ o! F( m/ b) t" a6 S3 I) I2 z! C" |% R
销。& N, ?( @8 k8 V- K. G3 @. T: b- o
: v: w+ U9 m8 F( f
1 ]" z; q5 q& h% N& X! C+ h最后,在《Practical Java》一书中Peter Haggar建议使用一个简单的数组Array来代替Vector: ?5 f& ]# D a
: A( v) T1 I$ }+ @2 g或ArrayList。尤其是对于执行效率要求高的程序更应如此。因为使用数组(Array)避免了同步、额外6 |2 a) t2 W# ~4 M
3 Z$ T/ ]% ?3 E2 q1 P/ I
的方法调用和不必要的重新分配空间的操作。