|
该用户从未签到
|
在项目开发中,我们可能往往需要动态的删除ArrayList中的一些元素。/ E8 l* _ w1 r9 ]
1 E+ F) _4 \$ x! F; ?一种错误的方式:+ o+ U( x5 W. T0 \1 N
8 e9 A6 D) ?$ U$ {, z1 i+ m<pre name="code" class="java">for(int i = 0 , len= list.size();i<len;++i){ 4 b8 Q$ w1 M+ p, k2 i
# G; \+ C U: `: N6 q; t if(list.get(i)==XXX){
5 y6 X0 t2 q* w; H% j
/ L& a2 y X+ i! @" m7 R list.remove(i); . E# |; |; e4 M5 h( |
, y6 ^$ [9 f' ]+ w* F
} ' B4 S/ W$ w+ x4 h2 c! z3 J
7 r$ b* |1 d! z# G( o& _6 T3 J6 u} , l8 o: _/ q, V* b9 ]6 \/ N2 H
上面这种方式会抛出如下异常:1 I( r0 O! e) _ L6 Z2 h) m
3 a) ]4 F' f# k! Y8 R& T
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 3, Size: 3 : U* o* p4 Y. P1 O
at java.util.ArrayList.RangeCheck(Unknown Source)
' ?# n0 u. s" ? at java.util.ArrayList.get(Unknown Source) / ]0 N% f# h0 ]' F- w& P' s
at ListDemo.main(ListDemo.java:20) * l" P7 A5 q+ [3 d( a1 R
因为你删除了元素,但是未改变迭代的下标,这样当迭代到最后一个的时候就会抛异常咯。9 E8 g4 Z" ^. x) I6 j8 R+ `
, d% z) m: c3 n& ]: x: y
可以对上面的程序进行如下改进:1 r6 M4 D' b! ~: {
* H1 M: w; l- L# X2 ufor(int i = 0 , len= list.size();i<len;++i){ / D. ?6 q/ {) E8 ]
/ m" t! X; h8 \
if(list.get(i)==XXX){
+ | l. y. N/ |7 z
1 f7 S8 D; s$ p+ R list.remove(i); + [1 S3 \, l, d
--len;//减少一个
6 z/ Q1 k, b! A% G( i }
- g* ~/ D( b) X' f7 S5 M! v" S% D
}
( m( ^) n; w) I/ V上面的代码就正确了。% a. J0 V3 F. N/ _ |8 a* T
( d' ]) J8 t3 w0 Y F7 H( b. v
下面我们再介绍一种方案:- } N6 S+ B& x, m( ^3 c
- O; @5 U7 u' J& ^$ h$ d6 MList接口内部实现了Iterator接口,提供开发者一个iterator()得到当前list对象的一个iterator对象。
- f* N% L! p& ~- h4 c G& Z& T4 z, l4 G; `! L! b) z* z4 r
Iterator<String> sListIterator = list.iterator(); : I v4 C* }2 H" f1 ^4 M( {5 ~
while(sListIterator.hasNext()){
, T. G9 A$ t T+ y. W4 k String e = sListIterator.next();
! b& k0 d3 p# W- s$ w- O# F if(e.equals("3")){ 1 Z% w2 d( k: N$ h3 ]. e# E
sListIterator.remove(); ; ]& o3 m0 q8 }$ u" q1 t+ W
} & ]) x( R' A! |; a3 I9 R V9 h# p4 A( V
}
4 Y- G& ~* ?7 u3 F. P上面这种也是正确的,并推荐使用第二种方案。- z1 W- m2 P! B0 }8 n+ y3 U U
, f/ i4 ~; K% t6 e8 ]: K6 c0 N' E
两种方案实现原理都差多的,第二种只是jdk封装了下。' N" `' P8 P5 P9 L H
1 l8 z5 G6 O! P5 e/ F. L查看ArrayList源码会发现很多方法内部都是基于iterator接口实现的,所以推荐使用第二种方案。 |! }9 j, H, a) }7 v) C( Z% w
% j8 V6 w4 D1 v( G4 A/ a% j |
|