该用户从未签到
|
在项目开发中,我们可能往往需要动态的删除ArrayList中的一些元素。
4 R3 I# ], ~6 ]- C% w/ Q6 X. p, _
! I, S2 o3 E4 |7 \% g+ a一种错误的方式:
& l1 F/ M$ g7 u+ P: J% c/ S8 M H" b* V8 f/ H, _, d
<pre name="code" class="java">for(int i = 0 , len= list.size();i<len;++i){ 8 t; m. W" |% [7 j) J! D1 D
" ?/ S. n0 Z% a3 Z: m) {8 j if(list.get(i)==XXX){
$ q& Y% c5 |% T' p% t! R1 C/ `8 C/ f3 \7 o- v
list.remove(i); 4 z8 {* x- B; B; _3 s( O, m9 i
% |5 d% O; e7 ?( h5 g. V
}
0 O4 ], g* `$ T/ f3 H' j
1 @& X: k" d3 g) u, I8 a+ o/ H}
2 }9 ~+ W$ H7 G8 [; J4 K) f上面这种方式会抛出如下异常:
0 _' g4 |) j$ z5 D0 P8 {& D# v! ?9 ]2 S
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 3, Size: 3
5 r% L8 i# G; j2 t at java.util.ArrayList.RangeCheck(Unknown Source) & ]& x/ ^7 ^: }, {
at java.util.ArrayList.get(Unknown Source) 8 `, U9 v/ x# n A$ M, a
at ListDemo.main(ListDemo.java:20) 0 E! D/ J- ]5 b: y& ^- c
因为你删除了元素,但是未改变迭代的下标,这样当迭代到最后一个的时候就会抛异常咯。0 X+ b1 S# \; K: Z6 z& N
0 u- T# N# j1 Q! `; e可以对上面的程序进行如下改进:6 @1 p# \5 o; K
7 @! w! D* ]4 L1 r
for(int i = 0 , len= list.size();i<len;++i){ / q$ d. R) Y- A8 B* I1 p5 ~! ~
8 {5 @6 w: z5 y2 \4 z& H
if(list.get(i)==XXX){ 5 X$ u! q; {2 H& l# R8 E
8 j) W' ~8 t* K list.remove(i); ! \0 s2 {8 K1 C+ \
--len;//减少一个
. Y' j# `! H+ y' B. Q9 m4 ~ }
( ~1 G" J6 \! |; ?$ u1 K, n3 \. t4 b
: Z2 v4 K+ |2 @- i I- `$ T}
1 _8 \! H+ A; z上面的代码就正确了。/ c$ D# Q8 r+ [# E3 N
' ]) @! U$ u0 B( s: h" h5 P
下面我们再介绍一种方案:
; h8 W; i( Y0 n0 S$ K
% R. C: u- p* `7 e) d; MList接口内部实现了Iterator接口,提供开发者一个iterator()得到当前list对象的一个iterator对象。
4 `& A3 x' _' o% w, k+ ?- i0 k- B+ w2 R9 T
Iterator<String> sListIterator = list.iterator(); / ]+ e! M0 l n6 J6 N- Q% M. _
while(sListIterator.hasNext()){
2 V( v( ~3 a) \ String e = sListIterator.next();
, t) u: \" i C8 Y if(e.equals("3")){
0 _% U" ?3 b8 @" T sListIterator.remove(); - a. _, [- U! K' G- @. v
}
8 S# C# R J3 N- d# e}
( `7 \" J$ h' h% q, p6 Q4 n3 Z上面这种也是正确的,并推荐使用第二种方案。/ q$ B: k6 r, Q6 b
3 J% h1 v% _( K; i6 y6 ~, k- B两种方案实现原理都差多的,第二种只是jdk封装了下。
3 V; K+ } ^1 m; W) { z! n+ _' T8 x1 O$ a) |& s- f
查看ArrayList源码会发现很多方法内部都是基于iterator接口实现的,所以推荐使用第二种方案。. ?$ k: h9 S3 G2 Y$ r, L& n
7 H6 j$ m6 {8 K/ |3 l |
|