TA的每日心情![](source/plugin/dsu_paulsign/img/emot/shuai.gif) | 衰 2021-2-2 11:21 |
---|
签到天数: 36 天 [LV.5]常住居民I
|
在项目开发中,我们可能往往需要动态的删除ArrayList中的一些元素。: r* R U% [7 X. j- N% M
4 ~3 S4 N- u& c1 k4 g0 `9 b一种错误的方式:
! C1 J4 I' S+ O# q2 e3 |) A& v( u: J) ~; \. b
<pre name="code" class="java">for(int i = 0 , len= list.size();i<len;++i){ $ O( P* M* S! h" G( u9 P/ D
. t2 O: l0 S% Q% j
if(list.get(i)==XXX){ 4 Z q* x: G. q3 }7 M2 ]% V! U
# |$ I6 V2 i6 E! K- i7 X$ J list.remove(i); 4 Z! d8 X6 v3 d$ A
; e1 G2 C5 U* p3 m9 z* }+ Y } ) P3 n5 _. S$ U% w! ?# p
6 `( E# @5 L4 G9 ]
} ' w. O5 g* K: q4 I) d( M
上面这种方式会抛出如下异常:( _% o- X0 }, p* m( |
D% B. |/ E& D1 k# j' k j% a8 {& _
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 3, Size: 3 , H: U9 `" T# J g( s( c: N+ i. ]
at java.util.ArrayList.RangeCheck(Unknown Source)
; `* m8 i/ U$ }4 G' c9 ~) X at java.util.ArrayList.get(Unknown Source) 8 J( Y1 _' M- k i: I
at ListDemo.main(ListDemo.java:20)
5 d" O) g u- c% l; U( b! Y因为你删除了元素,但是未改变迭代的下标,这样当迭代到最后一个的时候就会抛异常咯。
* R1 G& k# s# n, j
5 U6 \5 s, m. P/ w可以对上面的程序进行如下改进:, C2 Y/ Y) A9 K. g3 u2 I
4 p$ Q7 J' F/ |3 G# Bfor(int i = 0 , len= list.size();i<len;++i){
* p, a! }. E8 y
3 _* f2 r4 M* B/ j5 Z if(list.get(i)==XXX){ 1 k) F- U0 I& x# c# S
$ X: |" C; V. U- o list.remove(i); 6 `3 m: A& u6 V
--len;//减少一个 8 s+ ~ j6 T5 D# d
} % @4 ^& u; b7 j
1 U7 ^% J. I' `" v}
( }6 ]8 N/ D: l7 {1 z) A: |" Q+ _上面的代码就正确了。
1 P" R( j% m) v; e7 q6 F0 k1 L/ [8 Y
下面我们再介绍一种方案:
" z+ C# C" S7 ~% c% D5 y4 D% ]# {$ q
List接口内部实现了Iterator接口,提供开发者一个iterator()得到当前list对象的一个iterator对象。
4 i: ]3 i$ ]" w, F, e2 E5 T( J) O# B9 A8 D2 X; J6 F
Iterator<String> sListIterator = list.iterator();
& @. b8 l: l( Vwhile(sListIterator.hasNext()){
1 }. J7 P1 i( n7 R* p7 ~4 S String e = sListIterator.next();
, G" h3 i* F; V; m if(e.equals("3")){ ' m6 U& \$ q# d9 V# N
sListIterator.remove();
: t* i+ W' g, D9 C+ n } / |. t7 ^- }* W( M: [
}
* z1 J! ]( o( N0 ^+ h7 c2 Q4 o上面这种也是正确的,并推荐使用第二种方案。! C T3 m$ `; i/ Y6 J" ]5 K/ B
7 v9 E- a( w( O, J; R两种方案实现原理都差多的,第二种只是jdk封装了下。
' d2 t& O2 m5 j X+ S: B6 ]$ `, {9 e s2 \8 D7 k9 `6 I; F
查看ArrayList源码会发现很多方法内部都是基于iterator接口实现的,所以推荐使用第二种方案。! ~9 o% L1 S0 O' p8 ^& h2 F
' N. W: Z0 H- X( o& C/ g+ a |
|