一、
1.迭代器模式是对遍历集合元素的抽象
2.The Iterator Pattern provides a way to access the elements of an aggregate object sequentially without exposing its underlying representation.
3.
二、
1.
package headfirst.designpatterns.iterator.dinermerger; public interface Iterator { boolean hasNext(); MenuItem next(); }
2.
1 package headfirst.designpatterns.iterator.dinermerger; 2 3 public class DinerMenuIterator implements Iterator { 4 MenuItem[] items; 5 int position = 0; 6 7 public DinerMenuIterator(MenuItem[] items) { 8 this.items = items; 9 } 10 11 public MenuItem next() { 12 MenuItem menuItem = items[position]; 13 position = position + 1; 14 return menuItem; 15 } 16 17 public boolean hasNext() { 18 if (position >= items.length || items[position] == null) { 19 return false; 20 } else { 21 return true; 22 } 23 } 24 }
3.
1 package headfirst.designpatterns.iterator.dinermerger; 2 3 import java.util.ArrayList; 4 5 public class PancakeHouseMenuIterator implements Iterator { 6 ArrayList<MenuItem> items; 7 int position = 0; 8 9 public PancakeHouseMenuIterator(ArrayList<MenuItem> items) { 10 this.items = items; 11 } 12 13 public MenuItem next() { 14 MenuItem item = items.get(position); 15 position = position + 1; 16 return item; 17 } 18 19 public boolean hasNext() { 20 if (position >= items.size()) { 21 return false; 22 } else { 23 return true; 24 } 25 } 26 }
4.
1 package headfirst.designpatterns.iterator.dinermerger; 2 3 public class DinerMenu implements Menu { 4 static final int MAX_ITEMS = 6; 5 int numberOfItems = 0; 6 MenuItem[] menuItems; 7 8 public DinerMenu() { 9 menuItems = new MenuItem[MAX_ITEMS]; 10 11 addItem("Vegetarian BLT", 12 "(Fakin') Bacon with lettuce & tomato on whole wheat", true, 2.99); 13 addItem("BLT", 14 "Bacon with lettuce & tomato on whole wheat", false, 2.99); 15 addItem("Soup of the day", 16 "Soup of the day, with a side of potato salad", false, 3.29); 17 addItem("Hotdog", 18 "A hot dog, with saurkraut, relish, onions, topped with cheese", 19 false, 3.05); 20 addItem("Steamed Veggies and Brown Rice", 21 "Steamed vegetables over brown rice", true, 3.99); 22 addItem("Pasta", 23 "Spaghetti with Marinara Sauce, and a slice of sourdough bread", 24 true, 3.89); 25 } 26 27 public void addItem(String name, String description, 28 boolean vegetarian, double price) 29 { 30 MenuItem menuItem = new MenuItem(name, description, vegetarian, price); 31 if (numberOfItems >= MAX_ITEMS) { 32 System.err.println("Sorry, menu is full! Can't add item to menu"); 33 } else { 34 menuItems[numberOfItems] = menuItem; 35 numberOfItems = numberOfItems + 1; 36 } 37 } 38 39 public MenuItem[] getMenuItems() { 40 return menuItems; 41 } 42 43 public Iterator createIterator() { 44 return new DinerMenuIterator(menuItems); 45 // To test Alternating menu items, comment out above line, 46 // and uncomment the line below. 47 //return new AlternatingDinerMenuIterator(menuItems); 48 } 49 50 // other menu methods here 51 }
5.
1 package headfirst.designpatterns.iterator.dinermerger; 2 3 import java.util.ArrayList; 4 5 public class PancakeHouseMenu implements Menu { 6 ArrayList<MenuItem> menuItems; 7 8 public PancakeHouseMenu() { 9 menuItems = new ArrayList<MenuItem>(); 10 11 addItem("K&B's Pancake Breakfast", 12 "Pancakes with scrambled eggs, and toast", 13 true, 14 2.99); 15 16 addItem("Regular Pancake Breakfast", 17 "Pancakes with fried eggs, sausage", 18 false, 19 2.99); 20 21 addItem("Blueberry Pancakes", 22 "Pancakes made with fresh blueberries", 23 true, 24 3.49); 25 26 addItem("Waffles", 27 "Waffles, with your choice of blueberries or strawberries", 28 true, 29 3.59); 30 } 31 32 public void addItem(String name, String description, 33 boolean vegetarian, double price) 34 { 35 MenuItem menuItem = new MenuItem(name, description, vegetarian, price); 36 menuItems.add(menuItem); 37 } 38 39 public ArrayList<MenuItem> getMenuItems() { 40 return menuItems; 41 } 42 43 public Iterator createIterator() { 44 return new PancakeHouseMenuIterator(menuItems); 45 } 46 47 public String toString() { 48 return "Objectville Pancake House Menu"; 49 } 50 51 // other menu methods here 52 }
6.
1 package headfirst.designpatterns.iterator.dinermerger; 2 3 public interface Menu { 4 public Iterator createIterator(); 5 }
7.
1 package headfirst.designpatterns.iterator.dinermerger; 2 3 public class MenuItem { 4 String name; 5 String description; 6 boolean vegetarian; 7 double price; 8 9 public MenuItem(String name, 10 String description, 11 boolean vegetarian, 12 double price) 13 { 14 this.name = name; 15 this.description = description; 16 this.vegetarian = vegetarian; 17 this.price = price; 18 } 19 20 public String getName() { 21 return name; 22 } 23 24 public String getDescription() { 25 return description; 26 } 27 28 public double getPrice() { 29 return price; 30 } 31 32 public boolean isVegetarian() { 33 return vegetarian; 34 } 35 public String toString() { 36 return (name + ", $" + price + " " + description); 37 } 38 }
8.
1 package headfirst.designpatterns.iterator.dinermerger; 2 3 public class Waitress { 4 Menu pancakeHouseMenu; 5 Menu dinerMenu; 6 7 public Waitress(Menu pancakeHouseMenu, Menu dinerMenu) { 8 this.pancakeHouseMenu = pancakeHouseMenu; 9 this.dinerMenu = dinerMenu; 10 } 11 12 public void printMenu() { 13 Iterator pancakeIterator = pancakeHouseMenu.createIterator(); 14 Iterator dinerIterator = dinerMenu.createIterator(); 15 16 System.out.println("MENU ---- BREAKFAST"); 17 printMenu(pancakeIterator); 18 System.out.println(" LUNCH"); 19 printMenu(dinerIterator); 20 21 } 22 23 private void printMenu(Iterator iterator) { 24 while (iterator.hasNext()) { 25 MenuItem menuItem = iterator.next(); 26 System.out.print(menuItem.getName() + ", "); 27 System.out.print(menuItem.getPrice() + " -- "); 28 System.out.println(menuItem.getDescription()); 29 } 30 } 31 32 public void printVegetarianMenu() { 33 printVegetarianMenu(pancakeHouseMenu.createIterator()); 34 printVegetarianMenu(dinerMenu.createIterator()); 35 } 36 37 public boolean isItemVegetarian(String name) { 38 Iterator breakfastIterator = pancakeHouseMenu.createIterator(); 39 if (isVegetarian(name, breakfastIterator)) { 40 return true; 41 } 42 Iterator dinnerIterator = dinerMenu.createIterator(); 43 if (isVegetarian(name, dinnerIterator)) { 44 return true; 45 } 46 return false; 47 } 48 49 50 private void printVegetarianMenu(Iterator iterator) { 51 while (iterator.hasNext()) { 52 MenuItem menuItem = iterator.next(); 53 if (menuItem.isVegetarian()) { 54 System.out.print(menuItem.getName()); 55 System.out.println(" " + menuItem.getPrice()); 56 System.out.println(" " + menuItem.getDescription()); 57 } 58 } 59 } 60 61 private boolean isVegetarian(String name, Iterator iterator) { 62 while (iterator.hasNext()) { 63 MenuItem menuItem = iterator.next(); 64 if (menuItem.getName().equals(name)) { 65 if (menuItem.isVegetarian()) { 66 return true; 67 } 68 } 69 } 70 return false; 71 } 72 }
9.
1 package headfirst.designpatterns.iterator.dinermerger; 2 3 import java.util.*; 4 5 public class MenuTestDrive { 6 public static void main(String args[]) { 7 PancakeHouseMenu pancakeHouseMenu = new PancakeHouseMenu(); 8 DinerMenu dinerMenu = new DinerMenu(); 9 10 Waitress waitress = new Waitress(pancakeHouseMenu, dinerMenu); 11 12 // Without iterators 13 //printMenu(); 14 15 // With iterators 16 waitress.printMenu(); 17 18 } 19 20 /* 21 * Without the Waitress, we need the code below... 22 */ 23 public static void printMenu() { 24 PancakeHouseMenu pancakeHouseMenu = new PancakeHouseMenu(); 25 DinerMenu dinerMenu = new DinerMenu(); 26 27 ArrayList<MenuItem> breakfastItems = pancakeHouseMenu.getMenuItems(); 28 MenuItem[] lunchItems = dinerMenu.getMenuItems(); 29 30 // Hiding implementation 31 System.out.println("USING FOR EACH"); 32 for (MenuItem menuItem : breakfastItems) { 33 System.out.print(menuItem.getName()); 34 System.out.println(" " + menuItem.getPrice()); 35 System.out.println(" " + menuItem.getDescription()); 36 } 37 for (MenuItem menuItem : lunchItems) { 38 System.out.print(menuItem.getName()); 39 System.out.println(" " + menuItem.getPrice()); 40 System.out.println(" " + menuItem.getDescription()); 41 } 42 43 // Exposing implementation 44 System.out.println("USING FOR LOOPS"); 45 for (int i = 0; i < breakfastItems.size(); i++) { 46 MenuItem menuItem = (MenuItem)breakfastItems.get(i); 47 System.out.print(menuItem.getName()); 48 System.out.println(" " + menuItem.getPrice()); 49 System.out.println(" " + menuItem.getDescription()); 50 } 51 52 for (int i = 0; i < lunchItems.length; i++) { 53 MenuItem menuItem = lunchItems[i]; 54 System.out.print(menuItem.getName()); 55 System.out.println(" " + menuItem.getPrice()); 56 System.out.println(" " + menuItem.getDescription()); 57 } 58 } 59 }
三、用java.util.Iterator
1.
1 package headfirst.designpatterns.iterator.dinermergercafe; 2 3 import java.util.Iterator; 4 5 public class DinerMenuIterator implements Iterator<MenuItem> { 6 MenuItem[] list; 7 int position = 0; 8 9 public DinerMenuIterator(MenuItem[] list) { 10 this.list = list; 11 } 12 13 public MenuItem next() { 14 MenuItem menuItem = list[position]; 15 position = position + 1; 16 return menuItem; 17 } 18 19 public boolean hasNext() { 20 if (position >= list.length || list[position] == null) { 21 return false; 22 } else { 23 return true; 24 } 25 } 26 27 public void remove() { 28 if (position <= 0) { 29 throw new IllegalStateException 30 ("You can't remove an item until you've done at least one next()"); 31 } 32 if (list[position-1] != null) { 33 for (int i = position-1; i < (list.length-1); i++) { 34 list[i] = list[i+1]; 35 } 36 list[list.length-1] = null; 37 } 38 } 39 40 }
2.
1 package headfirst.designpatterns.iterator.dinermergercafe; 2 3 import java.util.Iterator; 4 5 public class DinerMenu implements Menu { 6 static final int MAX_ITEMS = 6; 7 int numberOfItems = 0; 8 MenuItem[] menuItems; 9 10 public DinerMenu() { 11 menuItems = new MenuItem[MAX_ITEMS]; 12 13 addItem("Vegetarian BLT", 14 "(Fakin') Bacon with lettuce & tomato on whole wheat", true, 2.99); 15 addItem("BLT", 16 "Bacon with lettuce & tomato on whole wheat", false, 2.99); 17 addItem("Soup of the day", 18 "Soup of the day, with a side of potato salad", false, 3.29); 19 addItem("Hotdog", 20 "A hot dog, with saurkraut, relish, onions, topped with cheese", 21 false, 3.05); 22 addItem("Steamed Veggies and Brown Rice", 23 "A medly of steamed vegetables over brown rice", true, 3.99); 24 addItem("Pasta", 25 "Spaghetti with Marinara Sauce, and a slice of sourdough bread", 26 true, 3.89); 27 } 28 29 public void addItem(String name, String description, 30 boolean vegetarian, double price) 31 { 32 MenuItem menuItem = new MenuItem(name, description, vegetarian, price); 33 if (numberOfItems >= MAX_ITEMS) { 34 System.err.println("Sorry, menu is full! Can't add item to menu"); 35 } else { 36 menuItems[numberOfItems] = menuItem; 37 numberOfItems = numberOfItems + 1; 38 } 39 } 40 41 public MenuItem[] getMenuItems() { 42 return menuItems; 43 } 44 45 public Iterator<MenuItem> createIterator() { 46 return new DinerMenuIterator(menuItems); 47 //return new AlternatingDinerMenuIterator(menuItems); 48 } 49 50 // other menu methods here 51 }
3.用hashmap
1 package headfirst.designpatterns.iterator.dinermergercafe; 2 3 import java.util.*; 4 5 public class CafeMenu implements Menu { 6 HashMap<String, MenuItem> menuItems = new HashMap<String, MenuItem>(); 7 8 public CafeMenu() { 9 addItem("Veggie Burger and Air Fries", 10 "Veggie burger on a whole wheat bun, lettuce, tomato, and fries", 11 true, 3.99); 12 addItem("Soup of the day", 13 "A cup of the soup of the day, with a side salad", 14 false, 3.69); 15 addItem("Burrito", 16 "A large burrito, with whole pinto beans, salsa, guacamole", 17 true, 4.29); 18 } 19 20 public void addItem(String name, String description, 21 boolean vegetarian, double price) 22 { 23 MenuItem menuItem = new MenuItem(name, description, vegetarian, price); 24 menuItems.put(menuItem.getName(), menuItem); 25 } 26 27 public Map<String, MenuItem> getItems() { 28 return menuItems; 29 } 30 31 public Iterator<MenuItem> createIterator() { 32 return menuItems.values().iterator(); 33 } 34 }