该用户从未签到
|
在项目开发中,我们可能往往需要动态的删除ArrayList中的一些元素。
2 k* z" B6 }+ Y4 r, ^0 T4 i
7 m* ^5 ]4 T! l. k. h# w+ A4 B% Y; g一种错误的方式:
) }9 F: {* H( z
- a4 u. m! a8 Z<pre name="code" class="java">for(int i = 0 , len= list.size();i<len;++i){
! q u4 {( I5 R6 D3 j, I
' V6 t0 H. ^" N4 h' }1 N if(list.get(i)==XXX){ 8 B3 c) X' R" W- g# f
2 q7 ?* j: r& p @3 ]0 ? list.remove(i);
$ f H2 W6 N& l4 Y/ ` b3 c/ U' m
/ H- c* M) F2 v6 R/ i& H8 C; S } 5 h+ c+ m- S/ m5 }9 U, q
! k$ B; t- Z7 g
}
$ X, K" u3 [1 E, Q9 `; k! C上面这种方式会抛出如下异常:% B0 W$ }0 ]7 N' q
/ J& i. H! n* W C7 v4 r! MException in thread "main" java.lang.IndexOutOfBoundsException: Index: 3, Size: 3 7 Z+ H! ^% |+ b) z8 Q1 L& x2 K
at java.util.ArrayList.RangeCheck(Unknown Source) ' e5 c. Q, k# r! i) P' X
at java.util.ArrayList.get(Unknown Source)
: t& |/ t0 Y; @ at ListDemo.main(ListDemo.java:20) % v5 S+ ^4 F& {/ g+ R0 Q2 D/ Z
因为你删除了元素,但是未改变迭代的下标,这样当迭代到最后一个的时候就会抛异常咯。
1 U- M4 s$ D2 g$ V: A$ B! J2 P( S, U4 F( j2 l- D5 L! o3 U+ q
可以对上面的程序进行如下改进:
& a' e- U- z2 L; W% \1 F1 O/ x3 Z' X6 _) r* G0 ?+ Q* A3 H) y* p
for(int i = 0 , len= list.size();i<len;++i){ 1 f) K3 z3 |* f# r3 z
S2 {' X/ L ?( A0 t* { if(list.get(i)==XXX){
4 k% _7 t2 A# a
6 L1 F8 U+ m3 z: K* K list.remove(i); # H! k1 S% P9 v9 @3 D; }6 _! U
--len;//减少一个
2 {6 z7 `$ w3 R' @; s8 _& L4 G }
5 y# I1 ~, N. J
, A, n; k# b* Z! O3 ~4 D}
4 p1 C- B! O7 E8 b上面的代码就正确了。/ ?2 d5 U O6 K+ v0 \ {; B6 d
$ Q" d4 y4 O% _7 ^# r下面我们再介绍一种方案:8 c3 d4 x) [9 _
: s. Z7 O3 D4 }9 @9 K0 x" O
List接口内部实现了Iterator接口,提供开发者一个iterator()得到当前list对象的一个iterator对象。
, Q% ^, _5 K4 j) o R2 v% _$ | x: T6 q
Iterator<String> sListIterator = list.iterator();
$ n! I+ M9 B' H9 Y4 x! h: mwhile(sListIterator.hasNext()){
4 l4 V4 ?# C/ L0 C String e = sListIterator.next(); . k, M7 S2 M3 {$ s# ~5 w) L& Y
if(e.equals("3")){
) Z& x+ T0 K X# h+ ~' V& @ sListIterator.remove(); d1 n1 ?) F* L4 M
}
3 z1 {' ^2 W$ n) {5 G}
' n& ]* n# S1 B/ j( ^7 X$ G上面这种也是正确的,并推荐使用第二种方案。
1 A4 [8 c0 K$ m" ?% v G; }. O- W( w0 K4 `: E, H
两种方案实现原理都差多的,第二种只是jdk封装了下。
1 ^ m' z# i! |& [! F) G, f6 v9 r
+ o i% c- }6 d& q6 r查看ArrayList源码会发现很多方法内部都是基于iterator接口实现的,所以推荐使用第二种方案。+ ^6 M% z, U& Q: r* H" \ C" d7 b8 B
$ U# g9 j' T5 h% ~ |
|