TA的每日心情 | 衰 2021-2-2 11:21 |
|---|
签到天数: 36 天 [LV.5]常住居民I
|
在项目开发中,我们可能往往需要动态的删除ArrayList中的一些元素。
4 x& J L$ H8 ~/ ~8 o
% w2 b5 }. g2 i! Z$ U一种错误的方式:& \' Q" W/ G. b* P; x8 e
; x6 h+ p; e7 Y<pre name="code" class="java">for(int i = 0 , len= list.size();i<len;++i){
# w- e4 f* a) ~6 u! J+ q$ e- a1 T# {5 F6 L5 ?- [/ L$ W1 l
if(list.get(i)==XXX){
+ q0 ?; a1 Y+ Z3 Q/ N9 _
& c5 r7 I6 Z) L) H( ~3 T) D* w5 n list.remove(i);
. W1 Z$ A# X6 N# m# P2 z; W9 U# ?# _
}
- t# f: O2 ]; J2 o E% p G" a# ~- r6 c% s1 M! u1 W2 J
} V2 P; V. b* V9 y. p; W& b% S
上面这种方式会抛出如下异常:
" p9 {6 O4 a: B( i7 p: F( b! y3 t; v m. s" @$ _
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 3, Size: 3 6 Y( v! n" V) m% X# f
at java.util.ArrayList.RangeCheck(Unknown Source)
) \: n4 q0 r1 I2 j% W* h: W- O) W4 a at java.util.ArrayList.get(Unknown Source)
0 _! R4 D8 {( t9 [# R at ListDemo.main(ListDemo.java:20)
: v% O/ D/ {; C0 T3 [8 K. C因为你删除了元素,但是未改变迭代的下标,这样当迭代到最后一个的时候就会抛异常咯。" B) _, |0 B8 `- `+ g
% k4 K" {: y; m
可以对上面的程序进行如下改进:
% X" K# M8 B# j$ [) B$ s& P0 g2 V; Q# c4 ]" d8 Z7 Q
for(int i = 0 , len= list.size();i<len;++i){ 0 ^( ^- Z5 A, Q! l4 P: n& \/ E
% q1 d- M8 H- E! P; g+ N
if(list.get(i)==XXX){
4 M& W+ i% x1 j: G, R% J; o/ ^- @0 T" }& p
list.remove(i);
4 D" L' _$ Z- u --len;//减少一个 & [4 I' }* V& e+ B" L& W
} + q8 K( I8 l2 g5 T2 c
6 C0 [* K( g% B$ L8 i6 T/ ?} ' t0 `. K# m8 d* e% q/ f* x
上面的代码就正确了。
9 c1 b' V, F! O: L/ x2 ~% n
' ^- k! p% f: @下面我们再介绍一种方案:- X0 w1 {$ [6 T8 K. R
7 u) h' c% v! M+ M( F3 w& m
List接口内部实现了Iterator接口,提供开发者一个iterator()得到当前list对象的一个iterator对象。
* V# ?7 V" _6 L/ j! G; Q
! o) K. q' C6 _Iterator<String> sListIterator = list.iterator(); * Y9 n ^% H" v; K( c
while(sListIterator.hasNext()){
& z6 Q ^* Q* |; B String e = sListIterator.next();
9 w: {7 W9 d2 y% P if(e.equals("3")){
, B. a6 h/ x% V" \+ Z* B/ j% D. a sListIterator.remove();
0 q5 P6 q9 b/ q3 Y$ d) J. F0 [ } : u) v, ?9 D/ u
} $ x Z" D" y0 J+ |
上面这种也是正确的,并推荐使用第二种方案。
, j* I7 J1 P+ l6 f3 }/ D) \6 F* j+ p' n5 \" m
两种方案实现原理都差多的,第二种只是jdk封装了下。
) l2 d3 i7 Y c; n6 F, `/ g$ v; n+ `: N4 K
查看ArrayList源码会发现很多方法内部都是基于iterator接口实现的,所以推荐使用第二种方案。
" v- [( x' [( |! K) S0 O4 h) Q* W0 E* {
|
|