|
该用户从未签到
|
在项目开发中,我们可能往往需要动态的删除ArrayList中的一些元素。2 m: H, h; D( f& R9 O3 I
2 A" v! e. Z9 V1 l9 e. t- L) A
一种错误的方式:: B; Z" d* E% N% M
B* z. `3 j8 _$ `! n. k# \<pre name="code" class="java">for(int i = 0 , len= list.size();i<len;++i){ 3 S6 J5 F8 g9 _5 ?$ O& a3 X4 I( ^
! V- K& r" b% C5 e# q1 r
if(list.get(i)==XXX){
1 |( y' B7 f4 p1 N. v# ^6 N' U, |
list.remove(i); * d7 `3 E9 E) ]3 H3 ]! U
( P( J5 Q% O1 P$ D } 9 m, K7 j- _7 ?2 `2 V
3 g! P* t# T% t- |3 R2 @2 c! ?- ~}
5 v$ ~ {+ R# I, g" U- `8 m上面这种方式会抛出如下异常:" _2 T9 G7 @0 F+ A' x: G% i
" x: Z, [- f9 L, d _9 o! `
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 3, Size: 3 1 l/ u' S' z1 X. B4 v9 m: u" l
at java.util.ArrayList.RangeCheck(Unknown Source) # e: y, u; D" ?% c$ y$ |
at java.util.ArrayList.get(Unknown Source)
4 [5 m" _2 ^ b' G# |2 A/ u at ListDemo.main(ListDemo.java:20)
* L: N/ v% m7 B) j1 Z/ }, r, H因为你删除了元素,但是未改变迭代的下标,这样当迭代到最后一个的时候就会抛异常咯。# U- Z0 ?+ o# v# E
* Y( x9 h1 `$ ?; ?5 \0 u; ~可以对上面的程序进行如下改进:. u4 I" ]- c7 ]4 Z, T. A" c
# s) X8 h( Z/ j9 i z
for(int i = 0 , len= list.size();i<len;++i){ - P- i, F. r' c" `
5 R& o4 A$ @3 H9 Q. l9 W8 k4 A if(list.get(i)==XXX){
" S3 f' O# z1 o& @! `, B1 q' f% L, |4 t
list.remove(i); # ?" ?, k5 j( L& v/ t! ]3 G
--len;//减少一个
, j0 ?; }: B- Q } * _6 ]8 ?9 x& u" d
5 g F" H: @0 V3 U7 h} 3 i) H1 W6 n) Q- V/ }5 {
上面的代码就正确了。
! G' Y/ M8 O N4 L h
- I" @3 L' i+ K: g# o% E下面我们再介绍一种方案:
; E' S2 `/ ?3 z5 z3 t- K# t
% t+ `, k: x5 k$ g" O" nList接口内部实现了Iterator接口,提供开发者一个iterator()得到当前list对象的一个iterator对象。% n# L- ?& e/ r, G% g
1 u! W& J5 z; J. j% t5 fIterator<String> sListIterator = list.iterator(); & y4 e7 P6 N* X; X! j. ^* C8 D
while(sListIterator.hasNext()){ 1 l$ B( Y8 X) P$ W- U0 M
String e = sListIterator.next(); 0 `" K) w6 w$ G" D- }- [
if(e.equals("3")){
6 w, [: C4 C7 \( l, h6 H sListIterator.remove();
* E" v" @4 r9 P0 P. Q/ k/ R }
+ y- B: o/ r T" {2 `6 M9 ]} 0 z2 _- ]3 [6 |0 w( D
上面这种也是正确的,并推荐使用第二种方案。9 V& |+ y, S L4 e( | ]+ ^# q
* J6 u# V% W( L: H" C% ~- \3 F两种方案实现原理都差多的,第二种只是jdk封装了下。
0 z: D/ f$ [# C2 S8 v! m, R' {& w; I. k" }3 l0 q' T
查看ArrayList源码会发现很多方法内部都是基于iterator接口实现的,所以推荐使用第二种方案。* g3 c2 D6 o# z
' C7 e) K; c. C |
|