TA的每日心情 | 衰 2021-2-2 11:21 |
---|
签到天数: 36 天 [LV.5]常住居民I
|
在项目开发中,我们可能往往需要动态的删除ArrayList中的一些元素。
8 o; K, B4 I `" F! `' I0 ^8 c2 N: r# L: C+ I
一种错误的方式:" G/ Y" g, F# B+ M- P# k
6 w& I1 u. }+ D6 H
<pre name="code" class="java">for(int i = 0 , len= list.size();i<len;++i){ ( b, y: |6 y3 [' @' o& I
W3 A3 `) Y, x
if(list.get(i)==XXX){
9 g8 P0 A- z8 ~" e, r' J& I8 C$ V4 z9 I, r
list.remove(i); - ]5 I. o' d3 J& n
* b# u: K$ x, ~
} $ {, Y( a8 X5 C
( C- e: T b3 C) W7 t
}
, C% k5 u% c# m+ |0 A上面这种方式会抛出如下异常:
# M! Y0 C" I- r1 P- ]5 K: h2 J7 \7 `: ]6 t$ S% w& Y
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 3, Size: 3
+ S- Z2 Q, h. C# L" M# `& j( \ at java.util.ArrayList.RangeCheck(Unknown Source) % s) H: \' n5 u5 l4 m
at java.util.ArrayList.get(Unknown Source)
3 D F* W F! H& N' T- h at ListDemo.main(ListDemo.java:20)
: b3 |* I/ ~% n- s因为你删除了元素,但是未改变迭代的下标,这样当迭代到最后一个的时候就会抛异常咯。
4 F7 m+ f( a# D+ [5 a$ V
# U8 |; S: D& B1 {( j可以对上面的程序进行如下改进:6 p* t$ W7 z4 g8 T& u' a. S# H* y; B/ i! \
9 b6 ]# x6 o7 Dfor(int i = 0 , len= list.size();i<len;++i){
- K% I! m- e7 C7 }" I x
8 d. w/ j% E- q if(list.get(i)==XXX){ , [" M1 d& u) c) @ `
7 O2 X; q* o& V: J' @
list.remove(i); + q8 m0 m" }/ ~) g S
--len;//减少一个 , W# ?+ S9 v( [7 F# b, @2 ~* P
} 1 a, c( b6 Y8 z3 R
5 `- m* A9 ^, T! E. g- w6 \
} ! N8 X1 a ]$ A5 |+ B- }, `2 V
上面的代码就正确了。
; a. [# I. e5 V1 N# h, F. _
/ d7 s A% d+ m: Y7 L* W, c+ Y9 O下面我们再介绍一种方案:9 |; V* U* i/ Z g$ S* \& d8 y
" j+ y# ]8 j' f! b DList接口内部实现了Iterator接口,提供开发者一个iterator()得到当前list对象的一个iterator对象。
' `' j& W1 P/ K; h/ W% N) z# E) _. S2 d. s" i4 `7 Q, r
Iterator<String> sListIterator = list.iterator();
' B$ A, {1 a: P6 m+ zwhile(sListIterator.hasNext()){ . Z7 R' X8 B5 g6 f% ^0 D1 l1 M
String e = sListIterator.next();
) f2 y ?0 ^: I# u if(e.equals("3")){
$ r2 Q1 b9 b: T: k/ c% B/ C; J sListIterator.remove(); ' g3 v8 H- W# ]
}
) d9 _$ K6 {# E- M- T} ! z, L. @: @$ C1 e$ v, V- v. i
上面这种也是正确的,并推荐使用第二种方案。3 t& u# Z6 c2 n5 |
l; m' R! I0 I% U' m- r- ~" Q
两种方案实现原理都差多的,第二种只是jdk封装了下。1 Q1 d- V$ d/ S/ U' { r5 A9 Z' T
( H7 y$ R+ k! \5 l6 w5 |查看ArrayList源码会发现很多方法内部都是基于iterator接口实现的,所以推荐使用第二种方案。
; ~: V( R: ?) u2 i. V# H/ L! P6 V0 j* `( ?5 d! ]( k$ W
|
|