在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)