TA的每日心情 | 衰 2021-2-2 11:21 |
|---|
签到天数: 36 天 [LV.5]常住居民I
|
在项目开发中,我们可能往往需要动态的删除ArrayList中的一些元素。
* s9 ]7 T w* p8 N, d* l! g: z/ z% G, A1 A" ?5 [
一种错误的方式:0 l+ A/ Y: v8 n3 R
+ l3 B! T. g) |( S) S<pre name="code" class="java">for(int i = 0 , len= list.size();i<len;++i){ & C* \ h% n0 |8 Z3 L& h: y
' V* d7 o* l9 b5 t. u6 O" ]4 } if(list.get(i)==XXX){ $ \) y0 ?+ n. C" P& U5 w
% Y) U5 e9 [$ z+ {- X! ^ list.remove(i); 0 Q3 O1 w: h1 V/ v: U. `
; C' O5 g; I4 P f9 H5 f1 m3 ? }
, P M8 M! {) p: a! b
3 T( c8 W& H8 J7 N; m y5 ~}
2 I; V" d7 J, S a; W- S4 M! z6 R# z; |上面这种方式会抛出如下异常:
) }, ]- ~# I- n1 a3 H& {2 U& b, |# Z
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 3, Size: 3
0 h9 ^, C4 c; T' a2 w at java.util.ArrayList.RangeCheck(Unknown Source) * s, F8 O1 ?# }8 D1 U
at java.util.ArrayList.get(Unknown Source) ; T/ u/ j) @8 D3 U. m6 q1 p
at ListDemo.main(ListDemo.java:20)
, b, m3 T" ^2 ]因为你删除了元素,但是未改变迭代的下标,这样当迭代到最后一个的时候就会抛异常咯。) |( Q0 Y3 t- E1 P: W8 i
3 J: ]/ @1 F7 I1 s' `, L! ]( p; ?可以对上面的程序进行如下改进:: L, j- @2 H$ x
+ }* \4 O6 Y& E/ W- i# E* i4 c
for(int i = 0 , len= list.size();i<len;++i){ & B) i# P4 [ _3 ~5 I7 y
* a% |1 J2 i4 M/ D& w6 U
if(list.get(i)==XXX){ 2 L }3 J6 u8 t5 I6 i
* _( f4 d: j6 t( x7 J list.remove(i);
4 z& E% a% c+ B, f% p! P+ \8 y- N --len;//减少一个 5 ^! a5 p: z' d/ A* G. H- A2 Q. x
}
9 x0 U! V9 k$ r3 W) v. R# D8 g8 K5 H- T, x+ f o
} . ~5 l( \, I) f, y
上面的代码就正确了。
) P$ y- V5 `, I. d3 _
6 `5 z* c1 ^: |. A下面我们再介绍一种方案:- | |8 a1 q3 Q4 u& c
) c$ q- O8 Y/ w7 v. I7 v" k2 M
List接口内部实现了Iterator接口,提供开发者一个iterator()得到当前list对象的一个iterator对象。
# y4 ^: {& k/ I: Y" q( ]
' h' N; q# |: r9 R0 KIterator<String> sListIterator = list.iterator();
" s# B' w Y7 r/ U# iwhile(sListIterator.hasNext()){ 1 T3 \. A+ Z/ N3 `2 C/ r: G
String e = sListIterator.next();
6 b. j- G2 \3 c9 N1 M- w! F' n/ L/ b if(e.equals("3")){ : K* j8 s5 F; }1 W* O% `6 A4 Z# f
sListIterator.remove();
9 E( ` D( e6 r, m8 r } ' R8 _9 q$ g- m# T
}
6 }4 }/ _6 V' M( d+ ~6 _上面这种也是正确的,并推荐使用第二种方案。
6 O* x: J5 d5 {! X& _
) v7 n7 l: b% @+ ^两种方案实现原理都差多的,第二种只是jdk封装了下。1 X& K, ^" v$ b" l$ n, b' _0 w4 M
0 l$ l- ]) ]5 J/ p( N" e查看ArrayList源码会发现很多方法内部都是基于iterator接口实现的,所以推荐使用第二种方案。
) u( T9 y1 w4 D3 K- v3 u6 P0 T
# b8 f" z# M1 P# Y( @ |
|