迭代器模式:对于一个容器中的一系列元素,提供一种按顺序访问其元素的方法,不考虑容器内部存储元素的结构。比如,集合可能有List, Set,Map,或者数组,不同的集合可以通过不同的方式来遍历,而迭代器模式就通过屏蔽这种不同来提供一种遍历元素的方式。
用个例子说明一下:
假设我们要遍历的元素是Phone:
public class Phone {
private String brand;
private Integer price;
public Phone(String brand, Integer price) {
this.brand = brand;
this.price = price;
}
@Override
public String toString() {
return "Phone{" +
"brand='" + brand + '\'' +
", price=" + price +
'}';
}
}
定义个迭代器的接口:
public interface Iterator<T> {
// 这个两个方法用来获取元素
boolean hasNext();
<T> T next();
}
具体的迭代器类
public class PhoneIterator implements Iterator<Phone>{
// 内部用来存储元素的集合,不对外暴露,这里也可以使用其他集合,比如数组等
private List<Phone> phoneList;
// 用于迭代返回元素时记录位置,默认值为起始位置
private int position = 0;
public PhoneIterator(List<Phone> phoneList) {
this.phoneList = phoneList;
}
@Override
public boolean hasNext() {
// 只要集合不为空,就可以继续返回
return phoneList.size() > position;
}
@Override
public Phone next() {
return phoneList.get(position++);
}
}
整合对象,里面提供一个方法可以获取迭代器对象
public class PhoneCollect{
// 和迭代器中的集合类型保持一致,这是内部实现逻辑,不对外暴露
private List<Phone> phoneList = new ArrayList<Phone>();
public void add(Phone phone) {
phoneList.add(phone);
}
public void remove(Phone phone) {
phoneList.remove(phone);
}
@Override
public Iterator<Phone> getIterator() {
return new PhoneIterator(phoneList);
}
}
测试:
public class Client {
public static void main(String[] args) {
PhoneCollect phoneCollect = new PhoneCollect();
phoneCollect.add(new Phone("huawei mate 60", 9999));
phoneCollect.add(new Phone("huawei nove 7pro", 3500));
phoneCollect.add(new Phone("xiaomi 12pro", 5500));
phoneCollect.add(new Phone("apple 14", 7800));
Iterator<Phone> iterator = phoneCollect.getIterator();
while (iterator.hasNext()){
Object next = iterator.next();
System.out.println(next);
}
}
}
迭代器在源码中有很多地方用到,大多数集合都提供了迭代器方法,获取一个集合的迭代器,然后调用迭代器的方法来获取对象,这就是迭代器模式的核心思想。