在Java中遍历List时会用到Java提供的Iterator,Iterator十分好用,缘由是:java
迭代器是一种设计模式,它是一个对象,它能够遍历并选择序列中的对象,而开发人员不须要了解该序列的底层结构。迭代器一般被称为“轻量级”对象,由于建立它的代价小。设计模式
Java中的Iterator功能比较简单,而且只能单向移动:安全
(1) 使用方法iterator()要求容器返回一个Iterator。第一次调用Iterator的next()方法时,它返回序列的第一个元素。注意:iterator()方法是java.lang.Iterable接口,被Collection继承。post
(2) 使用next()得到序列中的下一个元素。this
(3) 使用hasNext()检查序列中是否还有元素。spa
(4) 使用remove()将迭代器新返回的元素删除。线程
只要看看下面这个例子就一清二楚了:设计
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
import
java.util.*;
public
class
Muster {
public
static
void
main(String[] args) {
ArrayList list =
new
ArrayList();
list.add(
"a"
);
list.add(
"b"
);
list.add(
"c"
);
Iterator it = list.iterator();
while
(it.hasNext()){
String str = (String) it.next();
System.out.println(str);
}
}
}
|
运行结果:code
a
b
c对象
能够看到,Iterator能够不用管底层数据具体是怎样存储的,都可以经过next()遍历整个List。
可是,具体是怎么实现的呢?背后机制究竟如何呢?
这里咱们来看看Java里AbstractList实现Iterator的源代码:
1
.
public
abstract
class
AbstractList<E>
extends
AbstractCollection<E>
implements
List<E> {
// List接口实现了Collection<E>, Iterable<E>
2
.
3
.
protected
AbstractList() {
4
. }
5
.
6
. ...
7
.
8
.
public
Iterator<E> iterator() {
9
.
return
new
Itr();
// 这里返回一个迭代器
10
. }
11
.
12
.
private
class
Itr
implements
Iterator<E> {
// 内部类Itr实现迭代器
13
.
14
.
int
cursor =
0
;
15
.
int
lastRet = -
1
;
16
.
int
expectedModCount = modCount;
17
.
18
.
public
boolean
hasNext() {
// 实现hasNext方法
19
.
return
cursor != size();
20
. }
21
.
22
.
public
E next() {
// 实现next方法
23
. checkForComodification();
24
.
try
{
25
. E next = get(cursor);
26
. lastRet = cursor++;
27
.
return
next;
28
. }
catch
(IndexOutOfBoundsException e) {
29
. checkForComodification();
30
.
throw
new
NoSuchElementException();
31
. }
32
. }
33
.
34
.
public
void
remove() {
// 实现remove方法
35
.
if
(lastRet == -
1
)
36
.
throw
new
IllegalStateException();
37
. checkForComodification();
38
.
39
.
try
{
40
. AbstractList.
this
.remove(lastRet);
41
.
if
(lastRet < cursor)
42
. cursor--;
43
. lastRet = -
1
;
44
. expectedModCount = modCount;
45
. }
catch
(IndexOutOfBoundsException e) {
46
.
throw
new
ConcurrentModificationException();
47
. }
48
. }
49
.
50
.
final
void
checkForComodification() {
51
.
if
(modCount != expectedModCount)
52
.
throw
new
ConcurrentModificationException();
53
. }
54
. }
55
.}
|
能够看到,实现next()是经过get(cursor),而后cursor++,经过这样实现遍历。
这部分代码不难看懂,惟一难懂的是remove操做里涉及到的expectedModCount = modCount;
在网上查到说这是集合迭代中的一种“快速失败”机制,这种机制提供迭代过程当中集合的安全性。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
import
java.util.*;
public
class
Muster {
public
static
void
main(String[] args) {
ArrayList list =
new
ArrayList();
list.add(
"a"
);
list.add(
"b"
);
list.add(
"c"
);
Iterator it = list.iterator();
while
(it.hasNext()){
String str = (String) it.next();
System.out.println(str);
list.add(
"s"
);
//添加一个add方法
}
}
}
|
运行结果:
a
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
at com.hasse.Muster.main(Muster.java:11)