HeadFirst设计模式之迭代器模式

时间:2023-03-08 21:53:09
HeadFirst设计模式之迭代器模式

一、

1.迭代器模式是对遍历集合元素的抽象

2.The Iterator Pattern provides a way to access the elements of an aggregate object sequentially without exposing its underlying representation.

3.

二、

HeadFirst设计模式之迭代器模式

1.

package headfirst.designpatterns.iterator.dinermerger;

public interface Iterator {
boolean hasNext();
MenuItem next();
}

2.

 package headfirst.designpatterns.iterator.dinermerger;

 public class DinerMenuIterator implements Iterator {
MenuItem[] items;
int position = 0; public DinerMenuIterator(MenuItem[] items) {
this.items = items;
} public MenuItem next() {
MenuItem menuItem = items[position];
position = position + 1;
return menuItem;
} public boolean hasNext() {
if (position >= items.length || items[position] == null) {
return false;
} else {
return true;
}
}
}

3.

 package headfirst.designpatterns.iterator.dinermerger;

 import java.util.ArrayList;

 public class PancakeHouseMenuIterator implements Iterator {
ArrayList<MenuItem> items;
int position = 0; public PancakeHouseMenuIterator(ArrayList<MenuItem> items) {
this.items = items;
} public MenuItem next() {
MenuItem item = items.get(position);
position = position + 1;
return item;
} public boolean hasNext() {
if (position >= items.size()) {
return false;
} else {
return true;
}
}
}

4.

 package headfirst.designpatterns.iterator.dinermerger;

 public class DinerMenu implements Menu {
static final int MAX_ITEMS = 6;
int numberOfItems = 0;
MenuItem[] menuItems; public DinerMenu() {
menuItems = new MenuItem[MAX_ITEMS]; addItem("Vegetarian BLT",
"(Fakin') Bacon with lettuce & tomato on whole wheat", true, 2.99);
addItem("BLT",
"Bacon with lettuce & tomato on whole wheat", false, 2.99);
addItem("Soup of the day",
"Soup of the day, with a side of potato salad", false, 3.29);
addItem("Hotdog",
"A hot dog, with saurkraut, relish, onions, topped with cheese",
false, 3.05);
addItem("Steamed Veggies and Brown Rice",
"Steamed vegetables over brown rice", true, 3.99);
addItem("Pasta",
"Spaghetti with Marinara Sauce, and a slice of sourdough bread",
true, 3.89);
} public void addItem(String name, String description,
boolean vegetarian, double price)
{
MenuItem menuItem = new MenuItem(name, description, vegetarian, price);
if (numberOfItems >= MAX_ITEMS) {
System.err.println("Sorry, menu is full! Can't add item to menu");
} else {
menuItems[numberOfItems] = menuItem;
numberOfItems = numberOfItems + 1;
}
} public MenuItem[] getMenuItems() {
return menuItems;
} public Iterator createIterator() {
return new DinerMenuIterator(menuItems);
// To test Alternating menu items, comment out above line,
// and uncomment the line below.
//return new AlternatingDinerMenuIterator(menuItems);
} // other menu methods here
}

5.

 package headfirst.designpatterns.iterator.dinermerger;

 import java.util.ArrayList;

 public class PancakeHouseMenu implements Menu {
ArrayList<MenuItem> menuItems; public PancakeHouseMenu() {
menuItems = new ArrayList<MenuItem>(); addItem("K&B's Pancake Breakfast",
"Pancakes with scrambled eggs, and toast",
true,
2.99); addItem("Regular Pancake Breakfast",
"Pancakes with fried eggs, sausage",
false,
2.99); addItem("Blueberry Pancakes",
"Pancakes made with fresh blueberries",
true,
3.49); addItem("Waffles",
"Waffles, with your choice of blueberries or strawberries",
true,
3.59);
} public void addItem(String name, String description,
boolean vegetarian, double price)
{
MenuItem menuItem = new MenuItem(name, description, vegetarian, price);
menuItems.add(menuItem);
} public ArrayList<MenuItem> getMenuItems() {
return menuItems;
} public Iterator createIterator() {
return new PancakeHouseMenuIterator(menuItems);
} public String toString() {
return "Objectville Pancake House Menu";
} // other menu methods here
}

6.

 package headfirst.designpatterns.iterator.dinermerger;

 public interface Menu {
public Iterator createIterator();
}

7.

 package headfirst.designpatterns.iterator.dinermerger;

 public class MenuItem {
String name;
String description;
boolean vegetarian;
double price; public MenuItem(String name,
String description,
boolean vegetarian,
double price)
{
this.name = name;
this.description = description;
this.vegetarian = vegetarian;
this.price = price;
} public String getName() {
return name;
} public String getDescription() {
return description;
} public double getPrice() {
return price;
} public boolean isVegetarian() {
return vegetarian;
}
public String toString() {
return (name + ", $" + price + "\n " + description);
}
}

8.

 package headfirst.designpatterns.iterator.dinermerger;

 public class Waitress {
Menu pancakeHouseMenu;
Menu dinerMenu; public Waitress(Menu pancakeHouseMenu, Menu dinerMenu) {
this.pancakeHouseMenu = pancakeHouseMenu;
this.dinerMenu = dinerMenu;
} public void printMenu() {
Iterator pancakeIterator = pancakeHouseMenu.createIterator();
Iterator dinerIterator = dinerMenu.createIterator(); System.out.println("MENU\n----\nBREAKFAST");
printMenu(pancakeIterator);
System.out.println("\nLUNCH");
printMenu(dinerIterator); } private void printMenu(Iterator iterator) {
while (iterator.hasNext()) {
MenuItem menuItem = iterator.next();
System.out.print(menuItem.getName() + ", ");
System.out.print(menuItem.getPrice() + " -- ");
System.out.println(menuItem.getDescription());
}
} public void printVegetarianMenu() {
printVegetarianMenu(pancakeHouseMenu.createIterator());
printVegetarianMenu(dinerMenu.createIterator());
} public boolean isItemVegetarian(String name) {
Iterator breakfastIterator = pancakeHouseMenu.createIterator();
if (isVegetarian(name, breakfastIterator)) {
return true;
}
Iterator dinnerIterator = dinerMenu.createIterator();
if (isVegetarian(name, dinnerIterator)) {
return true;
}
return false;
} private void printVegetarianMenu(Iterator iterator) {
while (iterator.hasNext()) {
MenuItem menuItem = iterator.next();
if (menuItem.isVegetarian()) {
System.out.print(menuItem.getName());
System.out.println("\t\t" + menuItem.getPrice());
System.out.println("\t" + menuItem.getDescription());
}
}
} private boolean isVegetarian(String name, Iterator iterator) {
while (iterator.hasNext()) {
MenuItem menuItem = iterator.next();
if (menuItem.getName().equals(name)) {
if (menuItem.isVegetarian()) {
return true;
}
}
}
return false;
}
}

9.

 package headfirst.designpatterns.iterator.dinermerger;

 import java.util.*;

 public class MenuTestDrive {
public static void main(String args[]) {
PancakeHouseMenu pancakeHouseMenu = new PancakeHouseMenu();
DinerMenu dinerMenu = new DinerMenu(); Waitress waitress = new Waitress(pancakeHouseMenu, dinerMenu); // Without iterators
//printMenu(); // With iterators
waitress.printMenu(); } /*
* Without the Waitress, we need the code below...
*/
public static void printMenu() {
PancakeHouseMenu pancakeHouseMenu = new PancakeHouseMenu();
DinerMenu dinerMenu = new DinerMenu(); ArrayList<MenuItem> breakfastItems = pancakeHouseMenu.getMenuItems();
MenuItem[] lunchItems = dinerMenu.getMenuItems(); // Hiding implementation
System.out.println("USING FOR EACH");
for (MenuItem menuItem : breakfastItems) {
System.out.print(menuItem.getName());
System.out.println("\t\t" + menuItem.getPrice());
System.out.println("\t" + menuItem.getDescription());
}
for (MenuItem menuItem : lunchItems) {
System.out.print(menuItem.getName());
System.out.println("\t\t" + menuItem.getPrice());
System.out.println("\t" + menuItem.getDescription());
} // Exposing implementation
System.out.println("USING FOR LOOPS");
for (int i = 0; i < breakfastItems.size(); i++) {
MenuItem menuItem = (MenuItem)breakfastItems.get(i);
System.out.print(menuItem.getName());
System.out.println("\t\t" + menuItem.getPrice());
System.out.println("\t" + menuItem.getDescription());
} for (int i = 0; i < lunchItems.length; i++) {
MenuItem menuItem = lunchItems[i];
System.out.print(menuItem.getName());
System.out.println("\t\t" + menuItem.getPrice());
System.out.println("\t" + menuItem.getDescription());
}
}
}

三、用java.util.Iterator

1.

 package headfirst.designpatterns.iterator.dinermergercafe;

 import java.util.Iterator;

 public class DinerMenuIterator implements Iterator<MenuItem> {
MenuItem[] list;
int position = 0; public DinerMenuIterator(MenuItem[] list) {
this.list = list;
} public MenuItem next() {
MenuItem menuItem = list[position];
position = position + 1;
return menuItem;
} public boolean hasNext() {
if (position >= list.length || list[position] == null) {
return false;
} else {
return true;
}
} public void remove() {
if (position <= 0) {
throw new IllegalStateException
("You can't remove an item until you've done at least one next()");
}
if (list[position-1] != null) {
for (int i = position-1; i < (list.length-1); i++) {
list[i] = list[i+1];
}
list[list.length-1] = null;
}
} }

2.

 package headfirst.designpatterns.iterator.dinermergercafe;

 import java.util.Iterator;

 public class DinerMenu implements Menu {
static final int MAX_ITEMS = 6;
int numberOfItems = 0;
MenuItem[] menuItems; public DinerMenu() {
menuItems = new MenuItem[MAX_ITEMS]; addItem("Vegetarian BLT",
"(Fakin') Bacon with lettuce & tomato on whole wheat", true, 2.99);
addItem("BLT",
"Bacon with lettuce & tomato on whole wheat", false, 2.99);
addItem("Soup of the day",
"Soup of the day, with a side of potato salad", false, 3.29);
addItem("Hotdog",
"A hot dog, with saurkraut, relish, onions, topped with cheese",
false, 3.05);
addItem("Steamed Veggies and Brown Rice",
"A medly of steamed vegetables over brown rice", true, 3.99);
addItem("Pasta",
"Spaghetti with Marinara Sauce, and a slice of sourdough bread",
true, 3.89);
} public void addItem(String name, String description,
boolean vegetarian, double price)
{
MenuItem menuItem = new MenuItem(name, description, vegetarian, price);
if (numberOfItems >= MAX_ITEMS) {
System.err.println("Sorry, menu is full! Can't add item to menu");
} else {
menuItems[numberOfItems] = menuItem;
numberOfItems = numberOfItems + 1;
}
} public MenuItem[] getMenuItems() {
return menuItems;
} public Iterator<MenuItem> createIterator() {
return new DinerMenuIterator(menuItems);
//return new AlternatingDinerMenuIterator(menuItems);
} // other menu methods here
}

3.用hashmap

 package headfirst.designpatterns.iterator.dinermergercafe;

 import java.util.*;

 public class CafeMenu implements Menu {
HashMap<String, MenuItem> menuItems = new HashMap<String, MenuItem>(); public CafeMenu() {
addItem("Veggie Burger and Air Fries",
"Veggie burger on a whole wheat bun, lettuce, tomato, and fries",
true, 3.99);
addItem("Soup of the day",
"A cup of the soup of the day, with a side salad",
false, 3.69);
addItem("Burrito",
"A large burrito, with whole pinto beans, salsa, guacamole",
true, 4.29);
} public void addItem(String name, String description,
boolean vegetarian, double price)
{
MenuItem menuItem = new MenuItem(name, description, vegetarian, price);
menuItems.put(menuItem.getName(), menuItem);
} public Map<String, MenuItem> getItems() {
return menuItems;
} public Iterator<MenuItem> createIterator() {
return menuItems.values().iterator();
}
}