TA的每日心情 | 衰 2021-2-2 11:21 |
---|
签到天数: 36 天 [LV.5]常住居民I
|
在项目开发中,我们可能往往需要动态的删除ArrayList中的一些元素。; l1 `: `/ g: Z8 ?4 h4 I* ?+ |
- G; D5 R4 X6 D5 d; Q+ `
一种错误的方式:5 J, C* q# e! ]" I- T" |2 y1 U7 t
2 f, F* P: k+ m- r<pre name="code" class="java">for(int i = 0 , len= list.size();i<len;++i){ 9 o# i7 E" R, e2 l! u: X R
" S& U+ X$ u6 y* D+ z6 f* J! ? if(list.get(i)==XXX){
F# S' H: U$ j) s) w
1 E& z5 R% C s$ I/ s; |; c# ^ list.remove(i);
0 E; Z9 S: t+ v: ?1 Q
" F, C. r1 W- i( k7 y }
. B' U! j& Q _6 u/ w
5 a4 d" r& S' ?8 \( z}
1 [" T U$ X% x* C( Y9 W# S上面这种方式会抛出如下异常:( s+ J3 h6 Q' Y5 V) [# ~
3 s( t% K9 l! K5 GException in thread "main" java.lang.IndexOutOfBoundsException: Index: 3, Size: 3 2 A% w J" p7 T
at java.util.ArrayList.RangeCheck(Unknown Source)
; k9 C9 U. R4 C) n( H! x2 d at java.util.ArrayList.get(Unknown Source)
' v% V" F* Z% ?/ V' K at ListDemo.main(ListDemo.java:20)
; B2 [( C) H" r" m$ v因为你删除了元素,但是未改变迭代的下标,这样当迭代到最后一个的时候就会抛异常咯。
+ M% ]" c6 X% C, K4 p" X. c2 l' [, Q; N% W
可以对上面的程序进行如下改进:
5 B+ {8 S; F+ B' V$ n2 n( P* {& P) M% C0 d- h
for(int i = 0 , len= list.size();i<len;++i){
D. @0 u c, n1 O+ J
5 A/ M* [5 w; f7 x if(list.get(i)==XXX){ : j3 X( L8 ~ x5 l
! X1 `6 @! a. n! w: [5 l
list.remove(i); 1 S$ L3 b( j4 T5 [
--len;//减少一个 " i1 d# {4 R0 X* l
}
3 R0 E) V# T n) U0 m5 l* f! a1 b9 u" D' I; y8 M3 j! T
} 2 g8 V6 x M) q/ A) E! G
上面的代码就正确了。
$ e" ^5 K: }5 X: c" {0 x
8 r" A% V ]7 `$ y下面我们再介绍一种方案:/ P! P( b. M/ C/ O9 H7 {2 r; D
$ b" x. i/ U) x; ^, Z! X
List接口内部实现了Iterator接口,提供开发者一个iterator()得到当前list对象的一个iterator对象。
& t: G/ W* S5 I# o
$ \. M2 |! F: Q6 fIterator<String> sListIterator = list.iterator();
q! y" @: G* G/ a% ?# {0 Xwhile(sListIterator.hasNext()){
# d9 X5 _5 s( a. ?0 D' h String e = sListIterator.next();
u8 q, L; m+ M3 f if(e.equals("3")){
& |3 R9 ?( C# |; |: C sListIterator.remove(); 8 Y; W1 G2 x4 j( O) A
} + C2 K3 }5 K) `1 f; c) t9 ~
}
/ o/ U1 ^& _5 B0 y上面这种也是正确的,并推荐使用第二种方案。
8 x* l! ?: G4 o' a4 L% _" C7 o _0 b. g1 h7 Q- h2 e6 g% n1 A% q
两种方案实现原理都差多的,第二种只是jdk封装了下。
! `8 @1 X/ _5 _' n1 l
' B5 O0 I0 p8 D+ E& ^/ V查看ArrayList源码会发现很多方法内部都是基于iterator接口实现的,所以推荐使用第二种方案。
+ }+ w& S4 F t7 D( {8 }& v
7 h4 f3 ]; E" t6 C* J0 m |
|