该用户从未签到
|
在项目开发中,我们可能往往需要动态的删除ArrayList中的一些元素。( s' s0 l v$ g, Y: l8 q- a1 J
7 E) P, z) H' h! [+ h: }+ i
一种错误的方式:- J8 [4 G2 m: b' W0 Q
- I5 h. d5 `9 [% }' ^5 J- C: P& A<pre name="code" class="java">for(int i = 0 , len= list.size();i<len;++i){ + B# r& ^$ p! m% h5 o+ \( e
2 h) N" H9 c' y% w( ]/ o7 O if(list.get(i)==XXX){
0 @; ?9 A9 c) m( {
6 n; K! v! G% s7 Z9 E0 O, { list.remove(i);
& Z( f, i; f9 U$ ^1 z9 d
/ r* j2 ^+ _$ p1 u+ G# Q } 6 I& T/ e* s0 s
* P8 X' w* a3 S4 J1 O) j
}
4 N: z1 X% k. n& m+ s上面这种方式会抛出如下异常:" I( Y3 n% ?: |/ _- }+ R
! v' x9 ^8 G$ z( x5 \) l2 n: t8 YException in thread "main" java.lang.IndexOutOfBoundsException: Index: 3, Size: 3
) `6 |" ]0 |: f, p# `9 q- J at java.util.ArrayList.RangeCheck(Unknown Source) $ s2 k/ @. t! W' N0 U: x: Z) J
at java.util.ArrayList.get(Unknown Source) & r, k: w! N* y$ P7 I$ a
at ListDemo.main(ListDemo.java:20)
$ H. U+ \ A z. Y. F因为你删除了元素,但是未改变迭代的下标,这样当迭代到最后一个的时候就会抛异常咯。
/ B1 i+ T: s- g5 |* x5 u3 b; G; M4 L7 n# Q* `- L
可以对上面的程序进行如下改进:( m8 j/ @5 P* d9 U
6 H8 b& D W/ Lfor(int i = 0 , len= list.size();i<len;++i){
9 Q# p0 `8 c, T: H4 o
7 m' `4 C6 J+ L) g. Q8 z if(list.get(i)==XXX){
% d; A1 `! Y8 u S! ~: ~: j0 c& R$ _
list.remove(i); 7 C3 b4 d0 T/ e5 O6 z
--len;//减少一个
. D% X1 s" b% C$ N } + D& W; _/ p5 K) R
" `/ u1 i' A: f/ l: C2 j2 J) k} O* C* C H3 s0 u1 G S* S' X
上面的代码就正确了。6 n# n3 C$ }+ b' O
3 |. I) z: x# \$ ]7 P7 x' X5 F
下面我们再介绍一种方案:" u% w; a0 J: I4 t" `4 c I
- d. h. u7 S Y. s8 P; cList接口内部实现了Iterator接口,提供开发者一个iterator()得到当前list对象的一个iterator对象。2 z/ O+ q K2 \# t7 B. ^: q
1 q9 ?: R" ]! y% K
Iterator<String> sListIterator = list.iterator(); 1 x3 r& r9 v& }+ n/ x
while(sListIterator.hasNext()){
2 h; X( B9 |; E, R String e = sListIterator.next();
/ a$ I9 j! Y( M [( G8 v2 A' v if(e.equals("3")){
) }1 N. |$ ?, e/ q sListIterator.remove(); % A4 E9 l0 Q% ]
} , @* Y7 `" g! K
} ! Z$ @9 H3 t/ e& V. Z
上面这种也是正确的,并推荐使用第二种方案。
3 \' g) I5 U- M, a* `' A# J( O2 {" ?: ~5 Y' K/ P5 a/ Y5 P
两种方案实现原理都差多的,第二种只是jdk封装了下。4 Y* d1 [: z. d+ F I. q
8 y& z- B+ P2 I( ]5 j$ D查看ArrayList源码会发现很多方法内部都是基于iterator接口实现的,所以推荐使用第二种方案。
4 t# F+ t8 F+ f6 \* ~( J
, p/ D" I" w& t6 C& s3 W3 ~" _2 a9 [4 h |
|