TA的每日心情 | 衰 2021-2-2 11:21 |
---|
签到天数: 36 天 [LV.5]常住居民I
|
在项目开发中,我们可能往往需要动态的删除ArrayList中的一些元素。
' m" R+ \7 r* L# m- H8 A E
( Y; N# `3 U9 j/ W& _' \! m9 }7 T一种错误的方式:
9 h8 Q: @4 U) W. X: c- b1 @
$ D) e1 w" Z9 T2 b2 o i<pre name="code" class="java">for(int i = 0 , len= list.size();i<len;++i){
+ [1 e; r# M. H- w3 Q% ]
' ^7 Y# c9 V# C4 s9 U* h# J$ l if(list.get(i)==XXX){
, E c" K! I8 k, h3 s$ V. B
* _& J( g1 H; g" G, l/ v% G list.remove(i);
; I" X( m/ e9 _$ A6 l$ |# ~% {
7 v1 n3 g& V$ `, o0 v } 6 D: \; a9 Z) i/ a- P4 u
; }5 G9 b3 j. Q& g) u} & h5 d6 K/ F4 }! K$ c
上面这种方式会抛出如下异常:
7 K' X7 g+ k, d$ Y+ |' H
6 V. r. E3 C% g# t) rException in thread "main" java.lang.IndexOutOfBoundsException: Index: 3, Size: 3 + M+ X" Z) ]* f: I, V' D4 Z
at java.util.ArrayList.RangeCheck(Unknown Source)
9 `. X; M2 `5 C) A4 ]% B1 V6 U at java.util.ArrayList.get(Unknown Source) 2 j$ L! V! Y' x# q
at ListDemo.main(ListDemo.java:20) 4 p8 @- u7 q5 c# q/ C
因为你删除了元素,但是未改变迭代的下标,这样当迭代到最后一个的时候就会抛异常咯。
. t+ h8 ~0 U& S, z
8 p8 @; s: Z" {7 B. l8 s6 {* t: z可以对上面的程序进行如下改进:& c: L- ]* F" Y
' |% P6 s! ]9 G$ U8 i, E& Pfor(int i = 0 , len= list.size();i<len;++i){ $ L9 Y5 S% R' w: e& f
# p- L, u6 T7 t9 F
if(list.get(i)==XXX){ , X; q* p7 Y$ d0 Z
) n9 y& s6 ^$ l" Z$ b) x& r
list.remove(i);
$ _2 j& u5 A1 b) T; d/ o --len;//减少一个 / z5 {4 I* E- o9 h* U6 }
} : H8 ]; { P, q% {+ d1 y2 Z
; n1 G% |( J5 r6 M$ i} - d& d6 b& q0 u
上面的代码就正确了。% M+ e3 {( j! q* m
# r3 Z" e& f: J
下面我们再介绍一种方案:
3 B/ H' m1 [* I, V* ~* Y/ ^0 L) }( y+ X: i- |
List接口内部实现了Iterator接口,提供开发者一个iterator()得到当前list对象的一个iterator对象。
6 z7 g' X# Y2 x5 G9 O8 y7 o$ m+ q# X3 @; d! M/ H0 X1 d
Iterator<String> sListIterator = list.iterator();
+ S: M, j3 p; n y8 Mwhile(sListIterator.hasNext()){ : p- z, n+ @! [5 j9 y
String e = sListIterator.next();
3 L+ |: [+ T* C if(e.equals("3")){ 3 c1 Q" f! a" O5 |! N0 M( L
sListIterator.remove();
`& h5 t" B6 |* X- n/ ~ }
! E" h# W9 B2 |: f, i" X& }7 X! v# W} 3 v% S8 w# v( R
上面这种也是正确的,并推荐使用第二种方案。# K6 D8 Z( z5 i8 f$ r
# q) a6 |, e4 a" {; N4 W3 B两种方案实现原理都差多的,第二种只是jdk封装了下。* a$ p1 W! C, L& K1 i
7 E* j/ M& S6 e查看ArrayList源码会发现很多方法内部都是基于iterator接口实现的,所以推荐使用第二种方案。9 T' c/ B( R4 K8 O
( W8 _& E( G7 B
|
|