TA的每日心情 | 衰 2021-2-2 11:21 |
---|
签到天数: 36 天 [LV.5]常住居民I
|
在项目开发中,我们可能往往需要动态的删除ArrayList中的一些元素。+ x9 A( N# j, {, C
3 X; m$ [0 B' ?# {: c9 ?一种错误的方式:9 g$ V" g! b" H9 Q$ P* m8 \! k
0 e g% G' d4 R9 o<pre name="code" class="java">for(int i = 0 , len= list.size();i<len;++i){
7 x q( U2 S5 S+ \& m: A6 y: X* X g1 a$ K: |# Y
if(list.get(i)==XXX){
7 G3 S) Q3 n' U+ @2 ` D0 ~4 k3 e$ s$ M1 j6 x: H$ V" \; e" o
list.remove(i);
7 P6 G9 o2 _: G4 H7 g; z9 p6 @
}
! K1 d* o1 Z! H2 ~5 b
7 q4 o% ?6 j! K, J}
N- D( M9 v0 l1 E& t3 e* X上面这种方式会抛出如下异常:% i6 F! W8 w+ V# n, X9 s
" i7 ]- v) U( F" d2 }% x) IException in thread "main" java.lang.IndexOutOfBoundsException: Index: 3, Size: 3
" L! J+ |3 m) h4 E$ C1 k& a at java.util.ArrayList.RangeCheck(Unknown Source) 3 W, v. K, \7 q- u( M+ l6 }
at java.util.ArrayList.get(Unknown Source)
" m; M% L0 d, W( A# U0 N/ Q; m at ListDemo.main(ListDemo.java:20) # _& L1 d" a: H5 w
因为你删除了元素,但是未改变迭代的下标,这样当迭代到最后一个的时候就会抛异常咯。
! _$ G0 C4 H, @* ]* X; U6 l8 \, V n3 t6 F
可以对上面的程序进行如下改进:
3 `, l3 w# e: P9 b1 u0 ^
! A4 C; ~# o+ h; Nfor(int i = 0 , len= list.size();i<len;++i){
4 _5 T9 M* O5 H0 u* [# ^ r/ y& k" F" m( F: _% Z2 G
if(list.get(i)==XXX){
, a/ Q$ G/ T0 ]$ Q/ c# a: z7 d! ]( L& V" i/ Y5 e! [2 k
list.remove(i); . @7 C4 R. X3 o/ V1 \, X, B
--len;//减少一个
& ^7 F r6 n2 q }
. Q6 G' V# D9 S2 a/ I M' |9 b) {' x- q% F9 j
} % l; p) N; ]( C G3 y' K: g. {
上面的代码就正确了。3 M/ @+ x: P8 P( r! A% s
% A) L* y! k/ x5 m
下面我们再介绍一种方案:1 }9 O8 ~7 V1 x% c
9 c( S- s' Y7 K; o: M' [; y$ d3 z- HList接口内部实现了Iterator接口,提供开发者一个iterator()得到当前list对象的一个iterator对象。
2 y6 j8 j. h7 s: J/ }" Q( H' _; R s+ G) ~6 ~* k; ^( I3 @
Iterator<String> sListIterator = list.iterator();
! [7 {$ z0 r9 W4 `# w7 Fwhile(sListIterator.hasNext()){ * {# w1 c+ n4 D8 X, q" D/ P4 }
String e = sListIterator.next(); 3 H9 Z* _, I! c4 B+ c
if(e.equals("3")){
0 U, |, t! ]- ~* q' y. ~ sListIterator.remove(); . Q6 z; y# H) [/ j/ J% N7 f$ }
} 7 j; N# ~) j5 ?/ c1 ?8 W
}
1 c# K1 Q! B: c$ o+ i上面这种也是正确的,并推荐使用第二种方案。+ ]1 ]( [5 U c1 v3 C* k2 i# t
8 s( x) \5 _! ] y7 C J
两种方案实现原理都差多的,第二种只是jdk封装了下。
7 E: @. Z5 l1 Y$ E" D; |$ W5 \* X; c1 ]+ M* r
查看ArrayList源码会发现很多方法内部都是基于iterator接口实现的,所以推荐使用第二种方案。! l5 U+ v8 O& P N/ D# y
$ g: k/ v# `. J
|
|