一、概念
迭代器模式:提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。
关系图:
二、应用实例
1.遍历不同类型的菜单。
关系图:
代码实现:
/**
* 迭代器接口,所有迭代器实现该接口
* Created by 韩信 on 2017-11-18.
*/
public interface Iterator {
boolean hasNext();
Object next();
}
DinerMenuIterator类
/**
* Created by 韩信 on 2017-11-18.
*/
public class DinerMenuIterator implements Iterator {
private MenuItem[] items;
int position = 0;
public DinerMenuIterator(MenuItem[] items){
this.items = items;
}
@Override
public boolean hasNext() {
if(position >= items.length || items[position]==null){
return false;
}
return true;
}
@Override
public Object next() {
MenuItem menuItem = items[position];
position ++;
return menuItem;
}
}
PancakeHouseMenuIterator类
import java.util.List;
/**
* Created by 韩信 on 2017-11-18.
*/
public class PancakeHosuseMenuIterator implements Iterator {
private List<MenuItem> list;
int position = 0;
public PancakeHosuseMenuIterator(List<MenuItem> list){
this.list = list;
}
@Override
public boolean hasNext() {
position++;
return position>=list.size()? false:true;
}
@Override
public Object next() {
return list.get(position);
}
}
Menu接口
/**
* 菜单接口
* Created by 韩信 on 2017-11-18.
*/
public interface Menu {
Iterator createIterator();
}
MenuItem类
/**
* 菜单描述
* Created by 韩信 on 2017-11-18.
*/
public class MenuItem {
String name;
String desceiption;
boolean vegetarian;
double price;
public MenuItem(String name,String desceiption,boolean vegetarian,double price){
this.name = name;
this.desceiption = desceiption;
this.vegetarian = vegetarian;
this.price = price;
}
}
DinerMenu类
/**
* Created by 韩信 on 2017-11-18.
*/
public class DinerMenu implements Menu{
static final int MAX_TIEMS = 6;
int numberOfItem = 0;
MenuItem[] menuItems;
public Iterator createIterator(){
return new DinerMenuIterator(this.menuItems);
}
public DinerMenu(){
menuItems = new MenuItem[MAX_TIEMS];
addItem("Vegetarian BLT","descript1",true,2.99);
addItem("BLT","descript2",false,2.99);
addItem("Soup of the day","descript3",false,3.29);
addItem("Hotdog","descript4",false,3.05);
}
public void addItem(String name,String desceiption,boolean vegetarian,double price){
MenuItem menuItem = new MenuItem(name,desceiption,vegetarian,price);
if(numberOfItem >= MAX_TIEMS){
System.out.println("menu is full!");
}else{
menuItems[numberOfItem] = menuItem;
numberOfItem ++;
}
}
public MenuItem[] getMenuItems() {
return menuItems;
}
}
PancakeHouseMenu类
import java.util.ArrayList;
import java.util.List;
/**
* Created by 韩信 on 2017-11-18.
*/
public class PancakeHouseMenu implements Menu {
private List<MenuItem> menus;
public PancakeHouseMenu(){
menus = new ArrayList<>();
addItem("K&B's Pancake Breakfast","descript1",true,2.99);
addItem("Regular Pancake Breakfast","descript2",false,2.99);
addItem("Blueberry Pancakes","descript3",true,3.49);
addItem("waffles","descript4",true,3.59);
}
public void addItem(String name,String desceiption,boolean vegetarian,double price){
MenuItem menuItem = new MenuItem(name,desceiption,vegetarian,price);
menus.add(menuItem);
}
@Override
public Iterator createIterator() {
return new PancakeHosuseMenuIterator(menus);
}
public List<MenuItem> getMenus() {
return menus;
}
}
测试:
/**
* Created by 韩信 on 2017-11-18.
*/
public class Test {
public static void main(String[] args) {
DinerMenu dinerMenu = new DinerMenu();
PancakeHouseMenu pancakeHouseMenu = new PancakeHouseMenu();
Iterator iterator = dinerMenu.createIterator();
Iterator iterator1 = pancakeHouseMenu.createIterator();
printMenu(iterator);
printMenu(iterator1);
}
private static void printMenu(Iterator iterator){
while (iterator.hasNext()){
MenuItem menuItem = (MenuItem) iterator.next();
System.out.println(menuItem.name);
}
}
}
三、优缺点
1.优点:
- 简化了遍历方式,对于对象集合的遍历,还是比较麻烦的,对于数组或者有序列表,我们尚可以通过游标来取得,但用户需要在对集合了解很清楚的前提下,自行遍历对象,但是对于hash表来说,用户遍历起来就比较麻烦了。而引入了迭代器方法后,用户用起来就简单的多了。
- 可以提供多种遍历方式,比如说对有序列表,我们可以根据需要提供正序遍历,倒序遍历两种迭代器,用户用起来只需要得到我们实现好的迭代器,就可以方便的对集合进行遍历了。
- 封装性良好,用户只需要得到迭代器就可以遍历,而对于遍历算法则不用去关心。
2.缺点:
- 对于比较简单的遍历(像数组或者有序列表),使用迭代器方式遍历较为繁琐,大家可能都有感觉,像ArrayList,我们宁可愿意使用for循环和get方法来遍历集合。