|
该用户从未签到
|
在项目开发中,我们可能往往需要动态的删除ArrayList中的一些元素。
0 c. e+ |; D q; v
2 g2 p7 ^0 |' @+ H8 O; y1 l& p一种错误的方式:
- E1 N. b3 z0 p3 S
& N" y4 f8 N0 G3 {3 C<pre name="code" class="java">for(int i = 0 , len= list.size();i<len;++i){ 5 {3 l+ o, y) }% [8 H2 i# q3 }& z/ a
; A* }/ I. Q, l+ Y* Y1 a
if(list.get(i)==XXX){ + ~0 F4 M& e4 T0 f' X
1 R- ]9 U& S$ u; h$ f. Y1 @. D. \ list.remove(i); / r5 P7 g6 d& S% J8 q1 C& E T/ J
6 R5 p( v9 u9 X! ]- Z6 z0 q } Q. I% f6 ^; o6 v
5 P1 t: L) v/ h* V# X- a* f$ G}
" {# }% Q* d1 [% b: w9 q上面这种方式会抛出如下异常:- z% U# K" u! L/ F2 N
$ }& I/ v; a4 ]8 y% X( P9 c$ v6 g
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 3, Size: 3
) i# E, ?5 m; D$ |% [6 ^" }2 ] at java.util.ArrayList.RangeCheck(Unknown Source) . S; X$ a% ]" f( h7 m4 [
at java.util.ArrayList.get(Unknown Source)
( H U# C( Z' u. [1 }1 O at ListDemo.main(ListDemo.java:20) $ F+ g! J5 r7 Q
因为你删除了元素,但是未改变迭代的下标,这样当迭代到最后一个的时候就会抛异常咯。
6 \; |8 P- ?% V+ ~# ~( j, R2 ]* o4 T- u) ]# X; l. N
可以对上面的程序进行如下改进:% m! x& a. i$ E! ~' ~
# k/ l3 k0 r7 W2 q1 K
for(int i = 0 , len= list.size();i<len;++i){ ! k2 {4 h, b# x& S$ ~% q8 s; w
1 |, i( K! }1 [9 |5 Q" t3 |0 i
if(list.get(i)==XXX){
. `) Q( f b- }1 j0 l4 j+ j, i" G) B3 M- f) g6 Y
list.remove(i);
" m6 |0 q* V1 b+ m --len;//减少一个 . _/ y) T0 T* A* B# G- G
} / ~$ h- Q7 x9 N
- l1 x8 F. A1 n( |% b# U% q2 C! S}
& L. A3 x7 _ F0 W4 I4 W2 l上面的代码就正确了。
( I) r0 I7 ?; I5 S B- Q' l& Y6 g5 F6 k& l; D: E- W- V% \
下面我们再介绍一种方案:, l( V, @; {! f. i! @; M7 F: U
! Q3 m9 _0 u8 q4 a
List接口内部实现了Iterator接口,提供开发者一个iterator()得到当前list对象的一个iterator对象。
& l* m+ _$ P' H, q" k
6 j- n% k _: ^ B4 f/ ^Iterator<String> sListIterator = list.iterator();
4 P$ e) U/ V0 Vwhile(sListIterator.hasNext()){ * L5 |# V7 Z5 I# C0 u$ I; J
String e = sListIterator.next();
/ @8 x1 F& M% Q) f if(e.equals("3")){ % ?+ J6 p2 |; w
sListIterator.remove();
2 S& ~& p/ L' ~) l }
/ W0 [5 b8 n0 b2 @6 _}
( G. d3 B9 S; ?! p5 b上面这种也是正确的,并推荐使用第二种方案。
8 s$ l" m7 H. @0 ?/ r) I/ V$ h, z5 s$ G$ ^ J/ [$ [6 h
两种方案实现原理都差多的,第二种只是jdk封装了下。; N7 L. v7 L/ X3 f' W. e
5 _! X5 b, a3 P5 Z. u% \
查看ArrayList源码会发现很多方法内部都是基于iterator接口实现的,所以推荐使用第二种方案。' a A5 f3 u: h0 @7 s
/ c0 {" ~; T" t6 _/ |. F* s7 i9 P9 d
|
|