该用户从未签到
|
在项目开发中,我们可能往往需要动态的删除ArrayList中的一些元素。! A6 I2 k8 {3 T- U. J1 c1 B
/ P, m9 X l9 ]. Q- z7 R# K8 w一种错误的方式:
1 P) d6 O! {6 P8 \. }2 _% C
; o; i5 O6 e5 ^8 j) L# c<pre name="code" class="java">for(int i = 0 , len= list.size();i<len;++i){
4 J' C+ u9 J Y! o
/ `6 u( h2 P7 W5 P- f* p; x5 V$ ` if(list.get(i)==XXX){ 2 O, E& u2 A' ^7 Q
2 Y7 E1 X& W$ n' U, j7 @4 T5 c
list.remove(i); + T( Y0 F, \ n$ {. {5 v
/ ]7 h. l9 o. `9 r# d }
' p0 B6 @+ |2 [. M2 t5 W! I0 m: d' t' s( d b
}
! G9 I: C. q2 ~0 }上面这种方式会抛出如下异常:
, M0 W% F5 X. x$ i6 u1 A" h) M
8 V$ O( t* [" x, |$ C6 s% m# GException in thread "main" java.lang.IndexOutOfBoundsException: Index: 3, Size: 3 / n9 k# Q8 e0 C+ h: O
at java.util.ArrayList.RangeCheck(Unknown Source)
- A6 D4 \! W- i% t! Y at java.util.ArrayList.get(Unknown Source)
; t9 k; _) O$ W5 K at ListDemo.main(ListDemo.java:20)
- Z/ I* @( r; F3 T2 r/ S因为你删除了元素,但是未改变迭代的下标,这样当迭代到最后一个的时候就会抛异常咯。6 X3 T8 S0 p0 l' a
. Q5 }, i! a2 j( N$ H5 F1 F ^- V- y) E
可以对上面的程序进行如下改进:! Y1 ]! O: D" C0 N
- d# E+ N& S6 \2 P! j' o
for(int i = 0 , len= list.size();i<len;++i){ + L8 ^& k% i, Q' V6 h* A$ v0 T
: _" V1 ~' b' o- M& v$ h if(list.get(i)==XXX){ + ]( l& ~0 m- c4 S4 B) L
( v& @! Z# B$ g/ w
list.remove(i); / Z, D7 X( @/ J, {
--len;//减少一个
. j. j |7 A4 S* m+ V/ u0 P9 ~ } . `' W! V* d) W A* ~
7 b6 I9 m8 V* u8 Y2 `! h" N& ]
} 8 W" V; X6 q9 u7 R: ?1 L ]
上面的代码就正确了。, N; \5 W# X& m; P+ x' k* I
6 q, Q( }6 j, t
下面我们再介绍一种方案:
8 x$ w4 J% y7 x8 z" b5 b& N1 N
" N4 v6 S$ u& Q7 ~ S% f* k8 j" I# P' xList接口内部实现了Iterator接口,提供开发者一个iterator()得到当前list对象的一个iterator对象。; r& o& H! I: `7 T0 G4 Z! @' @& k
# Y# w0 Y$ d4 s$ u$ w/ uIterator<String> sListIterator = list.iterator(); H6 ^. |% ~9 {
while(sListIterator.hasNext()){ 9 {: y$ M' L8 z$ t u
String e = sListIterator.next();
3 l7 R$ v0 N% P+ s4 n O/ M if(e.equals("3")){ ( u! J" c" p( I& T& Q# [9 @! w
sListIterator.remove(); 9 f) n. Q4 E7 L: ~
}
6 S( \- ^8 [. z& q% x; y8 ]} ( v/ h9 w! e Z! i% @ w
上面这种也是正确的,并推荐使用第二种方案。
3 B; H. u$ M, m1 a2 a5 ~) c% a. N# L
两种方案实现原理都差多的,第二种只是jdk封装了下。
3 [2 e# c. f! j0 W7 R
% z6 f7 T: r$ S; z$ P查看ArrayList源码会发现很多方法内部都是基于iterator接口实现的,所以推荐使用第二种方案。
7 Z0 ?0 H9 F1 u1 O
1 O( P; a. u. w6 y |
|