该用户从未签到
|
在项目开发中,我们可能往往需要动态的删除ArrayList中的一些元素。& }$ a; f# E* k f9 i. I9 t% G! A
6 s# {( Q& G) S$ j9 t- V
一种错误的方式:* t3 E1 G$ j+ _* Q7 J& v
* F+ g& U# n W2 t& z6 k5 U, I<pre name="code" class="java">for(int i = 0 , len= list.size();i<len;++i){ * `+ j R% m/ x
: w1 E7 V; V; n$ U5 ? \; C
if(list.get(i)==XXX){ & p, x# Z9 m# A* Y5 w P6 d7 v
/ G% U3 b( }' U0 M, o. L list.remove(i);
: B5 F2 C8 C, e( W8 p; o/ _# a5 v; u1 c+ A2 F' H. @# u
} # X3 A! W$ e4 K+ G# g1 y
! m+ C: w) V M# w" ]0 ?
}
1 A1 F$ @0 z! n# O9 i上面这种方式会抛出如下异常:
8 G8 O7 }% u/ k7 t* Q
- L' A0 v$ M* B6 R0 S7 N1 _; ?Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 3, Size: 3 7 H4 c' i5 h6 b0 M
at java.util.ArrayList.RangeCheck(Unknown Source)
! F& B$ u3 k" d) y5 ~, B at java.util.ArrayList.get(Unknown Source)
% d! A3 y. g0 U- L0 O2 ?+ _ at ListDemo.main(ListDemo.java:20) , u' {4 L* z1 f# \$ u0 Y" K
因为你删除了元素,但是未改变迭代的下标,这样当迭代到最后一个的时候就会抛异常咯。; z' W/ f4 L( q/ Q( ]3 B
% o% \# z5 ]) [) P, y! g1 G% l( i
可以对上面的程序进行如下改进:: U* N9 E6 s L! C; g, k
: ]' ^8 `9 {) Bfor(int i = 0 , len= list.size();i<len;++i){ 7 [) h" C: |) C" q* Q4 N
8 f' r1 o& R7 P$ T$ { if(list.get(i)==XXX){
" D+ L7 [2 R8 ~ g6 h! }' R/ R' ?$ k- ]: f. v& b% o
list.remove(i);
l/ A: P" J4 y" C8 P, C --len;//减少一个 5 n7 l7 B- g A, X- V9 r% I7 V
} & n. W1 }! i! u% }/ I& n
) {& i6 [4 ?9 \" R}
# m4 c' u( b5 J" E. C( @/ C* {5 ^# {2 T上面的代码就正确了。- |1 h. j" D" U/ ^8 Q
0 I6 W. U3 D: ~; o, i
下面我们再介绍一种方案:
+ [( x, |, `/ V; e8 z; t1 [5 Q! ~+ o$ t3 N) O" H9 J
List接口内部实现了Iterator接口,提供开发者一个iterator()得到当前list对象的一个iterator对象。6 n( |. Q3 p+ k0 i1 S' \
$ ^6 W7 D8 `( S0 w9 e# y: p
Iterator<String> sListIterator = list.iterator(); # u; ?" J" `4 J4 q; e
while(sListIterator.hasNext()){ " I' z& D4 [4 ?# _
String e = sListIterator.next();
) ]9 s1 l+ j- i, J if(e.equals("3")){ ; U3 |) |# d% L6 {, Z! ]
sListIterator.remove(); # x8 r1 Y" s6 v: Z% V( h3 f+ _
}
& T+ E3 w5 k U" k' Z$ K3 J7 z5 C} + n! c, {# ~5 r$ V# M8 [
上面这种也是正确的,并推荐使用第二种方案。
6 G: Y4 G! r6 F! }! r6 O' t$ M9 z2 I7 u6 l! _! y7 @$ C1 i; `- f! I
两种方案实现原理都差多的,第二种只是jdk封装了下。5 J- |! Y9 {" t! C* `
- w( @+ z" T. ~& Z9 E; o
查看ArrayList源码会发现很多方法内部都是基于iterator接口实现的,所以推荐使用第二种方案。: V8 X; @+ ^) t( v
$ o: T' B; u& _1 x6 x! s0 W3 x |
|