TA的每日心情 | 衰 2021-2-2 11:21 |
|---|
签到天数: 36 天 [LV.5]常住居民I
|
在项目开发中,我们可能往往需要动态的删除ArrayList中的一些元素。
: E' k" B% C7 {" M9 Q) L6 k$ W; k* ?, o7 C6 a2 `' E- d
一种错误的方式:9 D' y3 G4 x7 t3 v: w
8 |) ~* X$ m% B- q. ^<pre name="code" class="java">for(int i = 0 , len= list.size();i<len;++i){
, r$ ^: k# Z% b Z1 _
; T- {. U" p( H6 V# L if(list.get(i)==XXX){
) I% v% c% G! O) U8 w+ V& q& ]- I
+ Y# E* i. M8 U7 A" a/ f2 S list.remove(i);
: d8 l/ R/ o0 N! K k. M1 D" y% q8 ]0 I0 u2 K
} - E, G5 @! T: W/ P
3 G0 i' y- V" A& Y# K
}
, [, m( B7 q7 }! S# w ^4 e- A/ O2 G上面这种方式会抛出如下异常:8 z' @5 s- e' J
7 ^' Y/ o# }5 f B( D N" wException in thread "main" java.lang.IndexOutOfBoundsException: Index: 3, Size: 3 , |8 Y! r- ^6 E5 r# `8 D# j
at java.util.ArrayList.RangeCheck(Unknown Source) * n k- M7 T0 d8 k
at java.util.ArrayList.get(Unknown Source)
% K1 L/ j: Y w at ListDemo.main(ListDemo.java:20) % @' L$ Z/ L. G
因为你删除了元素,但是未改变迭代的下标,这样当迭代到最后一个的时候就会抛异常咯。
. P9 O! m1 H( ^+ K& [7 X! g1 B( l0 @+ N* T" O
可以对上面的程序进行如下改进:- v# D* I! h: z2 Z/ ?. A
4 Y5 C$ i# E3 g/ ?# u1 N. P2 k6 qfor(int i = 0 , len= list.size();i<len;++i){ ! f# s! R/ s) h
, T8 k- L6 \" k$ Y) V if(list.get(i)==XXX){ ( \; e6 L3 i8 ~( s
0 ^6 s/ X; O. D' x" J0 G) J( X list.remove(i); ! C; c9 @6 \& j% B; @
--len;//减少一个
1 y' R/ `. z0 Z! j7 E }
5 I; V6 ]/ ?% B' H* H1 {# B/ Y2 [7 ]# |1 L" x! _% Y, e
}
: N% q8 C- q9 s. ^# k7 ^上面的代码就正确了。
/ q% ^. G7 |6 \' F
6 k6 v% b, }! H2 y/ ]1 K下面我们再介绍一种方案:+ V9 Y2 s; u! B! z
6 |' a# Z# G& W* O, yList接口内部实现了Iterator接口,提供开发者一个iterator()得到当前list对象的一个iterator对象。
1 U" X" r! R- R& _7 A6 I. n# \! D+ h* @ s/ E8 ^: R
Iterator<String> sListIterator = list.iterator(); - n( W( R2 [" w7 l# J. B0 ?3 V
while(sListIterator.hasNext()){
: e3 r2 z% v: n! V T g0 C. K String e = sListIterator.next(); 8 q1 \- o9 ]& T! y" _5 V; H
if(e.equals("3")){ , C/ G4 W$ B# Y ]6 c, d
sListIterator.remove(); / P; Q3 e$ p: R% y( D
}
, q+ T# g$ C0 }: ~. l+ n6 M1 I! O}
: X3 D7 h$ l! d+ n5 w2 b上面这种也是正确的,并推荐使用第二种方案。
) |) j6 D' {, k7 H m7 ~/ x) R5 V
两种方案实现原理都差多的,第二种只是jdk封装了下。8 b/ ^" n# h/ Y
E3 R4 a5 t3 |$ ^/ t" z
查看ArrayList源码会发现很多方法内部都是基于iterator接口实现的,所以推荐使用第二种方案。
8 I7 t$ |/ v3 N6 b; N; Q
: J& z! @: J# S6 d3 J$ ^ |
|