TA的每日心情 | 衰 2021-2-2 11:21 |
---|
签到天数: 36 天 [LV.5]常住居民I
|
在项目开发中,我们可能往往需要动态的删除ArrayList中的一些元素。$ U7 Z- t* o v# | f
& S" X6 E* s7 B
一种错误的方式:1 m8 H: T Q4 @/ C" u7 N9 J
3 i$ f g6 N1 i+ J! d& V0 Q<pre name="code" class="java">for(int i = 0 , len= list.size();i<len;++i){ ) X$ P0 L% o2 Y4 c
4 ?) ` ?# @) H X
if(list.get(i)==XXX){ * _: ^# ~; P" C( G
$ J: f# M* \6 Z# e: O list.remove(i);
( l: H! [1 |& V: C& S
( E& O' C: y0 m$ x8 m" h | } 7 L y* V0 |. a) ^4 U
6 u6 @* C3 }. N7 \* J, y c
}
- ? C# N9 w: ]6 A6 q- Z上面这种方式会抛出如下异常:
3 _# o6 B* ^" k8 B4 x/ c% ]' X: A9 r1 X; l1 c, y# C
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 3, Size: 3
( z/ ?' M; J" a0 E/ \# _# x at java.util.ArrayList.RangeCheck(Unknown Source)
6 k3 K! `$ p! d( A: L at java.util.ArrayList.get(Unknown Source)
( T0 c5 u1 D# e% f$ y, Q3 y( n at ListDemo.main(ListDemo.java:20) / v( o( S/ I# z) Q: w. F1 e
因为你删除了元素,但是未改变迭代的下标,这样当迭代到最后一个的时候就会抛异常咯。
# X6 N, Z0 c0 z- P& V/ ?! I# b2 k$ t; A' C4 s! Q; s- i
可以对上面的程序进行如下改进:6 ^5 C* r, V2 P/ F
# X3 n- Z3 H @for(int i = 0 , len= list.size();i<len;++i){
& S/ p, r& F, ? |# {
3 A# E. ~: P/ x8 ^9 g; l if(list.get(i)==XXX){ ( G/ ~' n; d, `
/ t' U) [0 P6 { a
list.remove(i);
' l- m# i2 n& T4 m; R2 \ --len;//减少一个
. p: d3 J5 T1 v9 [ }
' p3 `" }( {/ }6 d
: `. I. Y+ X, K% S( Z: V6 ~}
8 _0 E7 p/ X8 R$ C* i) N T; f* m上面的代码就正确了。
6 S5 x. \' T L0 }8 C) f
$ Q$ l2 `, i; ?5 O& K' q下面我们再介绍一种方案:
* B5 z% g, ~4 l7 W$ l4 ~* e' ?# H2 C' ?' U p$ f
List接口内部实现了Iterator接口,提供开发者一个iterator()得到当前list对象的一个iterator对象。: Q D% ~, s; X
1 l* I& T7 _* V1 S9 G
Iterator<String> sListIterator = list.iterator();
. z- p: `4 e! e9 _# z* W' xwhile(sListIterator.hasNext()){
1 Q* J" P& A, `# n9 S String e = sListIterator.next(); 8 H) w4 m5 `( ] H/ W
if(e.equals("3")){ 2 |1 j. J( [7 ^0 R) }8 [! ~
sListIterator.remove(); # J, C5 @# _+ x2 K' B
} 5 ~2 } K* J: ~* `& }7 a @
}
& o+ `5 [( ^* ~+ k5 @ s) \* k) V上面这种也是正确的,并推荐使用第二种方案。
6 ?- ~6 p" }. |5 Q9 V0 S1 r/ h- B% L$ S- g4 X
两种方案实现原理都差多的,第二种只是jdk封装了下。1 w* b- j8 y$ h! ~# e! v
: S2 a- @ ], T- M; t s查看ArrayList源码会发现很多方法内部都是基于iterator接口实现的,所以推荐使用第二种方案。( p9 g9 H$ q+ z1 s# u
( g* {9 C, j' i( r2 `+ g. [
|
|