该用户从未签到
|
在项目开发中,我们可能往往需要动态的删除ArrayList中的一些元素。* P$ C9 n- u% Y& m: D. }4 N
& [3 {5 Q; R' }4 J
一种错误的方式:3 p( _( T/ S" A
5 x) d+ a& [3 F B<pre name="code" class="java">for(int i = 0 , len= list.size();i<len;++i){
5 o, W4 j( m9 n% `2 |! T
. Q/ d: W: y5 F2 Y if(list.get(i)==XXX){
8 h. R: q5 g" e8 }
4 ~# S: W( Z" C2 i4 O1 O- A list.remove(i); ' s0 u% M! I" k6 h0 ^+ l8 h
0 X) S% b; u& A/ y6 _ } ! r- B8 M! P. K5 w, U( f" H
; a3 v* N& X7 x* q5 Q7 [}
5 u3 `" Z J* `* t上面这种方式会抛出如下异常:
1 e P/ c' F3 M" v* F x j0 U6 ]; W, B# R" W
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 3, Size: 3
: \$ Y K# R& D. Q; ]1 S4 R at java.util.ArrayList.RangeCheck(Unknown Source)
9 U5 W) }0 I- Z# ] H at java.util.ArrayList.get(Unknown Source)
: S; n# `$ ?" N7 I* ?% t6 W9 z. i at ListDemo.main(ListDemo.java:20) . y* t& a. T6 r( M
因为你删除了元素,但是未改变迭代的下标,这样当迭代到最后一个的时候就会抛异常咯。
, }* c* ?( a( c7 t" s7 m3 r% ^9 V& e# H+ X! W3 `
可以对上面的程序进行如下改进:% j* |' c1 x4 C( |* T- w
) Y% C2 e# L% H( @8 L
for(int i = 0 , len= list.size();i<len;++i){
) H5 F' p) Z( t8 m6 {+ A% c4 N& S+ U
3 y' B' V* _% E" `, y) Y( Z3 y if(list.get(i)==XXX){ $ P$ X/ p( P4 L( l
8 i) ?, A5 A+ X; A) V: C% E list.remove(i);
4 b# l( q6 Y2 w% L6 K1 [6 ^4 z( H --len;//减少一个 , @' n8 h2 u$ H
} 5 K4 n0 N2 j& A% n
5 F: g( N1 E1 ~: s9 g
} ( `. N8 t; Q5 O! @
上面的代码就正确了。" |7 `& w! E6 u% Q4 y( \9 P5 A
7 v' L% o M8 ?/ ~2 ?" r$ Y; X
下面我们再介绍一种方案:: v, I7 O; V% f* D9 I! T
: ?) @( F, O. X4 ~9 J
List接口内部实现了Iterator接口,提供开发者一个iterator()得到当前list对象的一个iterator对象。$ C5 s6 l8 z# j! h# j
8 g; I. A J4 L3 f" R( D+ m
Iterator<String> sListIterator = list.iterator();
, A, b9 E1 d1 P+ `while(sListIterator.hasNext()){ 3 M% k w' I( Y! d2 n1 @
String e = sListIterator.next();
1 Z* L% W _6 y4 z9 B if(e.equals("3")){ 6 ~' s0 z+ o- S. i) A9 x
sListIterator.remove(); $ ^- l( `6 ?' {; n( C) E: R( ~( p8 ^- l
} A. E; C: v1 T% h6 ^4 P; C, ~0 y' Z
}
4 r! s; Y; P: t# q上面这种也是正确的,并推荐使用第二种方案。
3 b9 M& m1 W3 L6 B. A8 Y, n8 S, E0 q! C6 d
两种方案实现原理都差多的,第二种只是jdk封装了下。
1 b% p3 l2 O c/ m7 j6 E6 \7 J' q/ d d" Q" E0 ]
查看ArrayList源码会发现很多方法内部都是基于iterator接口实现的,所以推荐使用第二种方案。
# v) y p; |+ y3 a) }( w) _/ U# u+ z3 O3 u
|
|