该用户从未签到
|
在项目开发中,我们可能往往需要动态的删除ArrayList中的一些元素。
8 K8 N, |7 G! P4 T6 m# W, s' J. m8 N( N( R' U
一种错误的方式:
2 F4 h0 U! \) {' n; ^- n; v/ K! `0 m2 h) e$ { s1 z9 D
<pre name="code" class="java">for(int i = 0 , len= list.size();i<len;++i){ ) _5 {' `. P1 }
) m' N6 g9 g( K# U c9 c if(list.get(i)==XXX){ 4 j% G: G4 t& J6 U: |
. G& Y! w' T( ~6 P' p( D8 r list.remove(i); ' @# z. m' P4 o/ o3 R4 ?+ E) o
2 ~; }! ?5 R. v. z# n4 {3 C }
7 s; R, _( m) z) b* n% ^" q" M( I% a- b3 {) U: t7 {( M
}
6 r) D; X3 m/ E4 }& `3 z上面这种方式会抛出如下异常:
( X7 h8 M, g0 v* B0 h7 k1 ~
& E* @8 Y0 p9 e1 y6 q5 ?) J$ `Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 3, Size: 3
$ }6 L g6 i7 x* Y @ at java.util.ArrayList.RangeCheck(Unknown Source)
8 V3 i, q5 i2 m% {, x at java.util.ArrayList.get(Unknown Source) ' x' H2 y6 Z9 ?- ^2 f4 N
at ListDemo.main(ListDemo.java:20) 0 M, p; _4 K! a0 F4 y8 m, C- o+ I
因为你删除了元素,但是未改变迭代的下标,这样当迭代到最后一个的时候就会抛异常咯。) f- n0 K1 D7 v1 P
- T' _4 \% }+ B/ \: H: n
可以对上面的程序进行如下改进:, t9 e5 ~: G. N6 V6 ?3 i0 ^ K+ i
. [% J( F: C) C$ d- i! tfor(int i = 0 , len= list.size();i<len;++i){ 5 \8 J/ ]- I% N3 x
" k8 T/ D" `8 ?& i7 q$ ? if(list.get(i)==XXX){ ( M0 t* r& n7 J$ G% X# Q: o
7 \$ a. E2 B4 Q2 {' B' ~$ G list.remove(i); : @; L% O0 y' j3 n
--len;//减少一个
" l" ~1 l7 `- f# K } - Y. A1 H2 F: Q5 A, J
4 H0 U3 r& }4 a# E- {} 0 s8 _/ Z* u# [3 i9 [7 N) v
上面的代码就正确了。
' o5 K; a( w F% N; z% B& A9 o6 x9 P$ {' I
下面我们再介绍一种方案:3 P5 m* V1 M R
7 A6 v/ f" W4 H- a8 D8 Z3 yList接口内部实现了Iterator接口,提供开发者一个iterator()得到当前list对象的一个iterator对象。3 y+ G% Y h" j5 I; m3 N
# M& _4 B5 f: I7 q S9 ?4 YIterator<String> sListIterator = list.iterator(); # o/ H7 r9 h- ?% I4 |6 l0 t p
while(sListIterator.hasNext()){ x+ Q: s! y. F+ u( X- n
String e = sListIterator.next(); 4 J5 k) h: b5 h3 [8 n% s
if(e.equals("3")){
2 C* j j3 W( K1 [/ Q c sListIterator.remove();
/ {5 L0 _/ f" Q; C0 Z9 e7 {1 h7 S } # j& O, _6 F& V5 b9 W
}
9 }) m9 ]: n. F" z4 S3 S3 @上面这种也是正确的,并推荐使用第二种方案。
4 c! I' z0 a& y4 q
' M: N6 w7 Z9 Y; E( q: t两种方案实现原理都差多的,第二种只是jdk封装了下。. H X5 {& G5 t
- y2 x/ t: j6 L9 ` A- V查看ArrayList源码会发现很多方法内部都是基于iterator接口实现的,所以推荐使用第二种方案。1 q# ~# ~0 X: H" f. Y9 O
+ F5 ?. \8 a" `' e |
|