概述
迭代器,提供了在不了解集合内部实现方法的时候遍历集合的能力。可以将容器内部实现与遍历操作隔离、解耦。
使用迭代器实现一个简单集合
通过自定义一个简单集合,并在对其使用迭代器进行遍历,达到掌握迭代器的目的。
集合描述
一个简单的集合,规则如下
- 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);
}
}
}