概述
迭代器,提供了在不瞭解集合內部實現方法的時候遍歷集合的能力。可以將容器內部實現與遍歷操作隔離、解耦。
使用迭代器實現一個簡單集合
通過自定義一個簡單集合,並在對其使用迭代器進行遍歷,達到掌握迭代器的目的。
集合描述
一個簡單的集合,規則如下
- 1、只能存放三個字符串
- 2、若插入第四個數據,則覆蓋第一個位置。
實現接口描述
Iterable接口描述
- 如果想用foreach對集合遍歷,則必須實現該接口。(具體原因在後面說明)
- iterator():是必須實現的接口,返回了一個迭代器。
Iterator
- 迭代器,可以對已知集合進行遍歷操作。
- hasNext():必須實現,返回一個boolean表示是否有下一個值
- next():必須實現,從集合中返回下一個元素。
代碼實現
自定義集合
/**
* 自定義集合
* 功能: 只能插入三個元素, 插入第四個元素會替換集合中第一個元素
* 實現了Iterable(可迭代)接口,必須要實現其中的iterator方法,返回一個迭代器
**/
public class MyCollection implements Iterable<String> {
String value1;
String value2;
String value3;
int currentValueIndex = 1;
public String get(int index) {
switch (index) {
case 1: return value1;
case 2: return value2;
case 3: return value3;
default: return null;
}
}
/**
* 添加一個元素, currentValueIndex爲當前元素索引, 表示下一次插入的位置
* 維護了一個只可以插入三個String的集合
* @param value
* @return
*/
public boolean add(String value) {
switch (currentValueIndex) {
case 1: value1 = value; currentValueIndex++; break;
case 2: value2 = value; currentValueIndex++; break;
case 3: value3 = value; currentValueIndex-=2; break;
default: break;
}
return true;
}
/**
* 返回我們自己定義的集合迭代器
* @return
*/
@Override
public Iterator<String> iterator() {
return new MyCollectionIterator(this);
}
}
自定義迭代器
自定義了一個迭代器,可以對上面自定義集合進行遍歷。
/**
* 給我自己實現的集合實現一個迭代器
* 必須實現的方法
* hasNext是否有下一個元素
* next取出下一個元素
*/
public class MyCollectionIterator implements Iterator<String> {
int index = 1;
int maxIndex = 3;
MyCollection myCollection;
public MyCollectionIterator(MyCollection myCollection) {
this.myCollection = myCollection;
}
/**
* 如果當前指針已經指向3,就沒有下一個了,返回false
* 否則還有下一個
* @return
*/
@Override
public boolean hasNext() {
if (index > maxIndex) {
return false;
}
return true;
}
/**
* 取出下一個元素,指針向前移動一步
* @return
*/
@Override
public String next() {
String result = myCollection.get(index);
index ++;
return result;
}
}
測試方法
public class Test {
public static void main(String[] args) {
MyCollection collection = new MyCollection();
collection.add("test1");
collection.add("test2");
collection.add("test3");
/**
* 循環1,獲取MyCollection的迭代器, 用while和next、hasNext遍歷我們的自定義集合
*/
Iterator<String> iterator = collection.iterator();
while (iterator.hasNext()) {
String str = iterator.next();
System.out.println(str);
}
/**
* 循環2,因爲我們的集合實現了Iterable接口,因此可以使用forEach循環
* 但是foreach循環編譯的結果是和循環1一模一樣的代碼
*/
for (String s : collection) {
System.out.println(s);
}
}
}
測試代碼反編譯結果
這裏是上述測試代碼反編譯後的代碼,可以看到,上面的循環2(foreach),已經被編譯成了和循環1一樣的結構。這裏可以看出,foreach循環最終其實是會使用iterator()方法獲取迭代器,來完成遍歷。因此如果想使用foreach循環,則必須實現Iterable接口。
public class Test {
public Test() {
}
public static void main(String[] args) {
MyCollection collection = new MyCollection();
collection.add("test1");
collection.add("test2");
collection.add("test3");
Iterator iterator = collection.iterator();
while(iterator.hasNext()) {
String str = (String)iterator.next();
System.out.println(str);
}
Iterator var5 = collection.iterator();
while(var5.hasNext()) {
String s = (String)var5.next();
System.out.println(s);
}
}
}