Java-Java程式設計思想第四版 第十九章 列舉型別 練習
阿新 • • 發佈:2019-02-20
練習1
// Use a static import to modify TrafficLight.java so you // don't have to qualify the enum instances. import static enumerated.Signal.*; public class Ja19_1{ Signal color = RED; public void change() { switch(color) { // Note that you don't have to say RED // in the case statement: case RED: color = GREEN; break; case GREEN: color = YELLOW; break; case YELLOW: color = RED; break; } } public String toString() { return "The traffic light is " + color; } public static void main(String[] args) { Ja19_1 t= new Ja19_1(); for(int i = 0; i < 7; i++) { print(t); t.change(); } } }
練習2
// Instead of implementing an interface, make next() a static // method. What are the benefits and drawbacks of this approach? //: enumerated/cartoons/EnumImplementation.java // An enum can implement an interface import java.util.*; import net.mindview.util.*; import static net.mindview.util.Print.*; enum CartoonCharacter{ SLAPPY, SPANKY, PUNCHY, SILLY, BOUNCY, NUTTY, BOB; public static CartoonCharacter next() { Random rand = new Random(); return values()[rand.nextInt(values().length)]; } } public class Ja19_2{ public static <T> void printNext(Generator<T> rg) { System.out.print(rg.next() + ", "); } public static void main(String[] args) { // Choose any instance: CartoonCharacter cc = CartoonCharacter.BOB; for(int i = 0; i < 10; i++) print(cc.next()); } }
練習3
// Add a new Course to Course.java and demonstrate that it works in Meal.java. import net.mindview.util.*; interface Food { enum Appetizer implements Food { SALAD, SOUP, SPRING_ROLLS; } enum MainCourse implements Food { LASAGNE, BURRITO, PAD_THAI, LENTILS, HUMMOUS, VINDALOO; } enum Dessert implements Food { TIRAMISU, GELATO, BLACK_FOREST_CAKE, FRUIT, CREME_CARAMEL; } enum Coffee implements Food { BLACK_COFFEE, DECAF_COFFEE, ESPRESSO, LATTE, CAPPUCCINO, TEA, HERB_TEA; } enum EE implements Food { A,B,C,D; } } enum Course { EE(Food.EE.class), APPETIZER(Food.Appetizer.class), MAINCOURSE(Food.MainCourse.class), DESSERT(Food.Dessert.class), COFFEE(Food.Coffee.class); private Food[] values; private Course(Class<? extends Food> kind) { values = kind.getEnumConstants(); } public Food randomSelection() { return Enums.random(values); } } ///:~ public class Ja19_3 { public static void main(String[] args) { for(int i = 0; i < 5; i++) { for(Course course : Course.values()) { Food food = course.randomSelection(); System.out.println(food); } System.out.println("---"); } } }
練習4
// Repeat the above (EX 3) for Ja19_4.java.
import net.mindview.util.*;
public enum Ja19_4 {
EE(Food.EE.class),
APPETIZER(Food.Appetizer.class),
MAINCOURSE(Food.MainCourse.class),
DESSERT(Food.Dessert.class),
COFFEE(Food.Coffee.class);
private Food[] values;
private Ja19_4(Class<? extends Food> kind) {
values = kind.getEnumConstants();
}
public interface Food {
enum Appetizer implements Food {
SALAD, SOUP, SPRING_ROLLS;
}
enum MainCourse implements Food {
LASAGNE, BURRITO, PAD_THAI,
LENTILS, HUMMOUS, VINDALOO;
}
enum Dessert implements Food {
TIRAMISU, GELATO, BLACK_FOREST_CAKE,
FRUIT, CREME_CARAMEL;
}
enum Coffee implements Food {
BLACK_COFFEE, DECAF_COFFEE, ESPRESSO,
LATTE, CAPPUCCINO, TEA, HERB_TEA;
}
enum EE implements Food {
A,B,C,D;
}
}
public Food randomSelection() {
return Enums.random(values);
}
public static void main(String[] args) {
for(int i = 0; i < 5; i++) {
for(Ja19_4 meal : Ja19_4.values()) {
Food food = meal.randomSelection();
System.out.println(food);
}
System.out.println("---");
}
}
}
練習5
/* Modify contol/VowelsAndConsonants.java so that it uses three enum types:
* VOWEL, SOMETIMES_A_VOWEL, and, CONSONANT. The enum constructor should
* take the various letters that describe that particular category. Hint:
* use varargs, and remember that varargs automatically creates an array
* for you.
*/
import java.util.*;
import static net.mindview.util.Print.*;
enum A{
VOWEL('a','o','e','i','u'),SOMETIMES_A_VOWEL('y','w'),CONSONANT('b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'v', 'x', 'z');
private Character[] ch;
private A(Character... letters){
ch=letters;
}
public static A letterType(Character c){
if(Arrays.asList(VOWEL.ch).contains(c))return VOWEL;
else if(Arrays.asList(SOMETIMES_A_VOWEL.ch).contains(c))return SOMETIMES_A_VOWEL;
else return CONSONANT;
}
}
public class Ja19_5{
public static void main(String[] args){
print(A.letterType('a').name());
}
}
練習6
/* Is there any special benefit in nexting Appetizer, MainCourse, Dessert, and
* Coffee inside Food rather than making them standalone enums that just happen
* to implement Food?
*/
//: enumerated/menu/Ja19_6.java
import net.mindview.util.*;
interface Food {}
enum Appetizer implements Food {
SALAD, SOUP, SPRING_ROLLS;
}
enum MainCourse implements Food {
LASAGNE, BURRITO, PAD_THAI,
LENTILS, HUMMOUS, VINDALOO;
}
enum Dessert implements Food {
TIRAMISU, GELATO, BLACK_FOREST_CAKE,
FRUIT, CREME_CARAMEL;
}
enum Coffee implements Food {
BLACK_COFFEE, DECAF_COFFEE, ESPRESSO,
LATTE, CAPPUCCINO, TEA, HERB_TEA;
}
public enum Ja19_6 {
APPETIZER(Appetizer.class),
MAINCOURSE(MainCourse.class),
DESSERT(Dessert.class),
COFFEE(Coffee.class);
private Food[] values;
private Ja19_6(Class<? extends Food> kind) {
values = kind.getEnumConstants();
}
public Food randomSelection() {
return Enums.random(values);
}
public static void main(String[] args) {
for(int i = 0; i < 5; i++) {
for(Ja19_6 meal : Ja19_6.values()) {
Food food = meal.randomSelection();
System.out.println(food);
}
System.out.println("---");
}
}
} /* Same output as Meal.java *///:~
練習7
練習8
// Modify PostOffice.java so it has the ability to forward mail.
import java.util.*;
import net.mindview.util.*;
import static net.mindview.util.Print.*;
class Mail {
// The NO's lower the probability of random selection:
enum GeneralDelivery {YES,NO1,NO2,NO3,NO4,NO5}
enum Scannability {UNSCANNABLE,YES1,YES2,YES3,YES4}
enum Readability {ILLEGIBLE,YES1,YES2,YES3,YES4}
enum Address {INCORRECT,OK1,OK2,OK3,OK4,OK5,OK6}
enum ReturnAddress {MISSING,OK1,OK2,OK3,OK4,OK5}
enum ForwardAddress {MISSING,OK1,OK2,OK3,OK4,OK5}
GeneralDelivery generalDelivery;
Scannability scannability;
Readability readability;
Address address;
ReturnAddress returnAddress;
ForwardAddress forwardAddress;
static long counter = 0;
long id = counter++;
public String toString() { return "Mail " + id; }
public String details() {
return toString() +
", General Delivery: " + generalDelivery +
", Address Scanability: " + scannability +
", Address Readability: " + readability +
", Address Address: " + address +
", Return address: " + returnAddress+
", Forward address: " + forwardAddress;
}
// Generate test Mail:
public static Mail randomMail() {
Mail m = new Mail();
m.generalDelivery= Enums.random(GeneralDelivery.class);
m.scannability = Enums.random(Scannability.class);
m.readability = Enums.random(Readability.class);
m.address = Enums.random(Address.class);
m.forwardAddress = Enums.random(ForwardAddress.class);
m.returnAddress = Enums.random(ReturnAddress.class);
return m;
}
public static Iterable<Mail> generator(final int count) {
return new Iterable<Mail>() {
int n = count;
public Iterator<Mail> iterator() {
return new Iterator<Mail>() {
public boolean hasNext() { return n-- > 0; }
public Mail next() { return randomMail(); }
public void remove() { // Not implemented
throw new UnsupportedOperationException();
}
};
}
};
}
}
public class Ja19_8 {
enum MailHandler {
GENERAL_DELIVERY {
boolean handle(Mail m) {
switch(m.generalDelivery) {
case YES:
print("Using general delivery for " + m);
return true;
default: return false;
}
}
},
MACHINE_SCAN {
boolean handle(Mail m) {
switch(m.scannability) {
case UNSCANNABLE: return false;
default:
switch(m.address) {
case INCORRECT:
switch(m.forwardAddress){
case MISSING: return false;
default:print("Delivering "+ m + " forward automatically");
return true;
}
default:
print("Delivering "+ m + " automatically");
return true;
}
}
}
},
VISUAL_INSPECTION {
boolean handle(Mail m) {
switch(m.readability) {
case ILLEGIBLE: return false;
default:
switch(m.address) {
case INCORRECT:
switch(m.forwardAddress){
case MISSING: return false;
default:print("Delivering "+ m + " forward normally");
return true;
}
default:
print("Delivering " + m + " normally");
return true;
}
}
}
},
RETURN_TO_SENDER {
boolean handle(Mail m) {
switch(m.returnAddress) {
case MISSING: return false;
default:
print("Returning " + m + " to sender");
return true;
}
}
};
abstract boolean handle(Mail m);
}
static void handle(Mail m) {
for(MailHandler handler : MailHandler.values())
if(handler.handle(m))
return;
print(m + " is a dead letter");
}
public static void main(String[] args) {
for(Mail mail : Mail.generator(10)) {
print(mail.details());
handle(mail);
print("*****");
}
}
}
練習9
// Modify class PostOffice so that it uses an EnumMap.
import java.util.*;
import net.mindview.util.*;
import static net.mindview.util.Print.*;
class Mail {
// The NO's lower the probability of random selection:
enum GeneralDelivery {YES,NO1,NO2,NO3,NO4,NO5}
enum Scannability {UNSCANNABLE,YES1,YES2,YES3,YES4}
enum Readability {ILLEGIBLE,YES1,YES2,YES3,YES4}
enum Address {INCORRECT,OK1,OK2,OK3,OK4,OK5,OK6}
enum ReturnAddress {MISSING,OK1,OK2,OK3,OK4,OK5}
GeneralDelivery generalDelivery;
Scannability scannability;
Readability readability;
Address address;
ReturnAddress returnAddress;
static long counter = 0;
long id = counter++;
public String toString() { return "Mail " + id; }
public String details() {
return toString() +
", General Delivery: " + generalDelivery +
", Address Scanability: " + scannability +
", Address Readability: " + readability +
", Address Address: " + address +
", Return address: " + returnAddress;
}
// Generate test Mail:
public static Mail randomMail() {
Mail m = new Mail();
m.generalDelivery= Enums.random(GeneralDelivery.class);
m.scannability = Enums.random(Scannability.class);
m.readability = Enums.random(Readability.class);
m.address = Enums.random(Address.class);
m.returnAddress = Enums.random(ReturnAddress.class);
return m;
}
public static Iterable<Mail> generator(final int count) {
return new Iterable<Mail>() {
int n = count;
public Iterator<Mail> iterator() {
return new Iterator<Mail>() {
public boolean hasNext() { return n-- > 0; }
public Mail next() { return randomMail(); }
public void remove() { // Not implemented
throw new UnsupportedOperationException();
}
};
}
};
}
}
interface Handler{boolean handle(Mail m);}
public class Ja19_9 {
enum MailHandler { GENERAL_DELIVERY, MACHINE_SCAN, VISUAL_INSPECTION, RETURN_TO_SENDER ; }
public static void handle(Mail m,EnumMap<MailHandler,Handler> em) {
for(Map.Entry<MailHandler,Handler> e: em.entrySet())
if(e.getValue().handle(m))
return;
print(m + " is a dead letter");
}
public static void main(String[] args){
EnumMap<MailHandler,Handler> em=new EnumMap<MailHandler,Handler>(MailHandler.class);
em.put(MailHandler.GENERAL_DELIVERY,new Handler(){
public boolean handle(Mail m) {
switch(m.generalDelivery) {
case YES:
print("Using general delivery for " + m);
return true;
default: return false;
}
}
});
em.put(MailHandler.MACHINE_SCAN,new Handler(){
public boolean handle(Mail m) {
switch(m.scannability) {
case UNSCANNABLE: return false;
default:
switch(m.address) {
case INCORRECT: return false;
default:
print("Delivering "+ m + " automatically");
return true;
}
}
}
});
em.put(MailHandler.VISUAL_INSPECTION,new Handler(){
public boolean handle(Mail m) {
switch(m.readability) {
case ILLEGIBLE: return false;
default:
switch(m.address) {
case INCORRECT: return false;
default:
print("Delivering " + m + " normally");
return true;
}
}
}
});
em.put(MailHandler.RETURN_TO_SENDER,new Handler(){
public boolean handle(Mail m) {
switch(m.returnAddress) {
case MISSING: return false;
default:
print("Returning " + m + " to sender");
return true;
}
}
});
for(Mail mail : Mail.generator(10)) {
print(mail.details());
handle(mail,em);
print("*****");
}
}
}
練習10
// Modify class VendingMachine (only) using EnumMap so that one
// program can have multiple instances of VendingMachine.
//import static enumerated.Input.*;
import java.util.*;
import net.mindview.util.*;
import static net.mindview.util.Print.*;
enum Input {
NICKEL(5), DIME(10), QUARTER(25), DOLLAR(100),
TOOTHPASTE(200), CHIPS(75), SODA(100), SOAP(50),
ABORT_TRANSACTION {
public int amount() { // Disallow
throw new RuntimeException("ABORT.amount()");
}
},
STOP { // This must be the last instance.
public int amount() { // Disallow
throw new RuntimeException("SHUT_DOWN.amount()");
}
};
int value; // In cents
Input(int value) { this.value = value; }
Input() {}
public int amount() { return value; }; // In cents
static Random rand = new Random(47);
public static Input randomSelection() {
// Don't include STOP:
return values()[rand.nextInt(values().length - 1)];
}
} ///:~
enum Category {
MONEY(Input.NICKEL, Input.DIME, Input.QUARTER, Input.DOLLAR),
ITEM_SELECTION(Input.TOOTHPASTE, Input.CHIPS, Input.SODA, Input.SOAP),
QUIT_TRANSACTION(Input.ABORT_TRANSACTION),
SHUT_DOWN(Input.STOP);
private Input[] values;
Category(Input... types) { values = types; }
private static EnumMap<Input,Category> categories =
new EnumMap<Input,Category>(Input.class);
static {
for(Category c : Category.class.getEnumConstants())
for(Input type : c.values)
categories.put(type, c);
}
public static Category categorize(Input input) {
return categories.get(input);
}
}
interface Command { // In order to use a Command Design Pattern
void next(Input input);
void next();
}
enum State {
RESTING,
ADDING_MONEY,
DISPENSING,
GIVING_CHANGE,
TERMINAL
}
public class Ja19_10 {
int id = ++count;
static int count = 0;
State state = State.RESTING;
int amount = 0; // for each transaction
int banked = 0; // retained after transactions
Input input = null;
Input selection = null;
boolean isTransient = false;
// Enums must be static, sot use classes instead:
class RestingDo implements Command {
public void next(Input in) {
isTransient = false;
input = in;
switch(Category.categorize(in)) {
case MONEY:
amount += in.amount();
state = State.ADDING_MONEY;
break;
case SHUT_DOWN:
state = State.TERMINAL;
default:
}
}
public void next() {
isTransient = false;
}
}
class AddingMoneyDo implements Command {
public void next(Input input) {
isTransient = false;
switch(Category.categorize(input)) {
case MONEY:
amount += input.amount();
break;
case ITEM_SELECTION:
selection = input;
if(amount < selection.amount()) {
print("Insufficient money for " + selection); }
else {
state = State.DISPENSING;
isTransient = true;
}
break;
case QUIT_TRANSACTION:
state = State.GIVING_CHANGE;
isTransient = true;
break;
case SHUT_DOWN:
state = State.TERMINAL;
banked = banked += amount;
default:
}
}
public void next() { isTransient = false; }
}
class DispensingDo implements Command {
public void next() {
isTransient = true;
print("Here is your " + selection);
state = State.GIVING_CHANGE;
}
public void next(Input input) {
isTransient = true;
print("Here is your " + selection);
state = State.GIVING_CHANGE;
}
}
class GivingChangeDo implements Command {
public void next(Input input) {
isTransient = true;
if(amount > selection.amount()) {
print("Your change: " + (amount - selection.amount()));
}
banked = banked += selection.amount();
amount = 0; // reset
state = State.RESTING;
}
public void next() {
isTransient = true;
if(amount < selection.amount())
print("Returning your: " + amount);
if(amount > selection.amount()) {
print("Your change: " + (amount - selection.amount()));
banked = banked += selection.amount();
}
if(amount == selection.amount())
banked = banked += selection.amount();
amount = 0;
state = State.RESTING;
}
}
class TerminalDo implements Command {
public void next(Input input) {
print("state TERMINAL");
isTransient = false;
}
public void next() {
print("state TERMINAL");
isTransient = false;
}
}
Map<State,Command> em =
Collections.synchronizedMap(new EnumMap<State,Command>(State.class));
Ja19_10() { // Load up the EnumMap in the constructor
print("Ja19_10()#" + id);
em.put(State.RESTING, new RestingDo());
em.put(State.ADDING_MONEY, new AddingMoneyDo());
em.put(State.DISPENSING, new DispensingDo());
em.put(State.GIVING_CHANGE, new GivingChangeDo());
em.put(State.TERMINAL, new TerminalDo());
}
void showAmount() { print("amount = " + amount); }
void showBanked() { print("banked = " + banked); }
public static void main(String[] args) {
Generator<Input> gen = new RandomInputGenerator();
if(args.length == 1)
gen = new FileInputGenerator10(args[0]);
Ja19_10 vm10a = new Ja19_10();
Ja19_10 vm10b = new Ja19_10();
Ja19_10 vm10c = new Ja19_10();
print();
print("Testing VendingMachine 10a:");
while(vm10a.state != State.TERMINAL) {
Input in = gen.next();
(vm10a.em.get(vm10a.state)).next(in);
while(vm10a.isTransient) {
(vm10a.em.get(vm10a.state)).next();
}
vm10a.showAmount();
}
vm10a.showBanked();
print();
print("Testing VendingMachine 10b:");
gen = new FileInputGenerator10("Ja19_10bInput.txt");
while(vm10b.state != State.TERMINAL) {
Input in = gen.next();
(vm10b.em.get(vm10b.state)).next(in);
while(vm10b.isTransient) {
(vm10b.em.get(vm10b.state)).next();
}
vm10b.showAmount();
}
print();
print("Testing VendingMachine 10c:");
gen = new FileInputGenerator10("Ja19_10cInput.txt");
while(vm10c.state != State.TERMINAL) {
Input in = gen.next();
(vm10c.em.get(vm10c.state)).next(in);
while(vm10c.isTransient) {
(vm10c.em.get(vm10c.state)).next();
}
vm10c.showAmount();
}
}
}
// Create inputs from a file of ';'-separated strings;
class FileInputGenerator10 implements Generator<Input> {
private Iterator<String> input;
public FileInputGenerator10(String fileName) {
input = new TextFile(fileName, ";").iterator();
}
public Input next() {
if(input.hasNext()) {
return Enum.valueOf(Input.class, input.next().trim());
}
return null;
}
}
class RandomInputGenerator implements Generator<Input> {
public Input next() { return Input.randomSelection(); }
}
練習11
// enumerated/VendingMachine11.java
// TIJ4 Chapter Enumerated, Exercise 11, page 1047
/* In a real vending machine you will want to easily add and change
* the type of vended items, so the limits imposed by an enum on
* Input are impractical (remember that enums are for a restricted set
* of types). Modify VendingMachine.java so that the vended items are
* represented by a class instead of being part of Input, and initialize
* an ArrayList of these objects from a text file
* (using net.mindview.util.TextFile).
*/
/* My solution to one of the exercises in
* Thinking in Java 4th Edition (by Bruce Eckel).
* It compiles and runs correctly using JDK 1.6.0
* @author Greg Gordon
* @author www.greggordon.org
* April, 2009
*/
/** Files required for input, in same package:
VendingMachineInput.txt
QUARTER;QUARTER;QUARTER;CHIPS;
DOLLAR; DOLLAR; TOOTHPASTE;
QUARTER; DIME; SODA;
QUARTER; DIME; NICKEL; SODA;
ABORT_TRANSACTION;
STOP;
VendingMachine11Input.txt:
Money:Nickel(5),Dime(10),Quarter(25),Dollar(100);Selection:Soda(100),Juice(125),
HotChocolate(100),Coffee(145),CandyBar(90);VendingEvent:AbortTransaction,Stop,
**/
import java.util.*;
import net.mindview.util.*;
import static net.mindview.util.Print.*;
// Vending elements as classes implementing common interface:
interface VendingInput { String name(); }
class MonetaryUnit implements VendingInput {
private String name;
private int amount = 0;
MonetaryUnit(String name, int amount) {
this.name = name;
this.amount = amount;
}
public String name() { return name; }
public int amount() { return amount; }
}
class VendedItem implements VendingInput {
private String name;
private int price = 0;
VendedItem(String name, int price) {
this.name = name;
this.price = price;
}
public String name() { return name; }
public int price() { return price; }
}
class VendingEvent implements VendingInput {
private String name;
VendingEvent(String name) {
this.name = name;
}
public String name() { return name; }
}
public class Ja19_11 {
private static State state = State.RESTING;
private static int amount = 0;
private static VendedItem selection = null;
enum StateDuration { TRANSIENT } // Tagging enum
enum State {
RESTING {
void next(VendingInput in) {
if(MonetaryUnit.class.isInstance(in)) {
amount += ((MonetaryUnit)in).amount();
state = ADDING_MONEY;
}
if(VendingEvent.class.isInstance(in)) {
if(((VendingEvent)in).name().equals("Stop"))
state = TERMINAL;
}
}
},
ADDING_MONEY {
void next(VendingInput in) {
if(MonetaryUnit.class.isInstance(in)) {
amount += ((MonetaryUnit)in).amount();
}
if(VendedItem.class.isInstance(in)) {
selection = (VendedItem)in;
if(amount < selection.price())
print("Insufficient money for " + selection.name());
else state = DISPENSING;
}
if(VendingEvent.class.isInstance(in)) {
if(((VendingEvent)in).name().equals("AbortTransaction"))
state = GIVING_CHANGE;
if(((VendingEvent)in).name().equals("Stop"))
state = TERMINAL;
}
}
},
DISPENSING(StateDuration.TRANSIENT) {
void next() {
print("here is your " + selection.name());
amount -= selection.price();
state = GIVING_CHANGE;
}
},
GIVING_CHANGE(StateDuration.TRANSIENT) {
void next() {
if(amount > 0) {
print("Your change: " + amount);
amount = 0;
}
state = RESTING;
}
},
TERMINAL { void output() { print("Halted"); } };
private boolean isTransient = false;
State() {} // no-arg constructor
State(StateDuration trans) { isTransient = true; }
void next(VendingInput in) {
throw new RuntimeException("Only call " +
"next(VendingInput in) for non-transient states");
}
void next() {
throw new RuntimeException("Only call next() for " +
"StateDuration.TRANSIENT states");
}
void output() { print(amount); }
}
static void run(Generator<VendingInput> gen) {
while(state != State.TERMINAL) {
state.next(((FileInputGenerator11)gen).next());
while(state.isTransient)
state.next();
state.output();
}
state = State.RESTING;
print();
}
static void runRandom(Generator<VendingInput> gen) {
while(state != State.TERMINAL) {
state.next(((FileInputGenerator11)gen).randomNext());
while(state.isTransient)
state.next();
state.output();
}
state = State.RESTING;
print();
}
static void runTextExample(Generator<VendingInput> gen) {
while(state != State.TERMINAL) {
// for(int i = 0; i < 16; i++) {
state.next(((FileInputGenerator11)gen).textExampleNext("VendingMachineInput.txt"));
while(state.isTransient)
state.next();
state.output();
}
state = State.RESTING;
print();
}
public static void main(String[] args) {
FileInputGenerator11 gen =
new FileInputGenerator11("VendingMachine11Input.txt");
runRandom(gen); // random vending inputs
run(gen);
runTextExample(gen); // inputs from VendingMachineInput.txt
}
}
class FileInputGenerator11 implements Generator<VendingInput> {
private ArrayList<String> list;
private List<VendingInput> vendList = new ArrayList<VendingInput>();
private Iterator<VendingInput> it;
private Random rand = new Random();
private Iterator<String> input = new TextFile("VendingMachineInput.txt", ";").iterator();
// Construct List of VendingInput from appropriately formatted txt file:
public FileInputGenerator11(String fileName) {
list = new TextFile(fileName, ",|;|:");
int m = list.indexOf("Money");
int se = list.indexOf("Selection");
int e = list.indexOf("VendingEvent");
VendingInput vIn;
for(String s : list) {
int x = list.indexOf(s);
if(m < x && x < se) {
String[] sa = s.split("\\(|\\)");
vIn = new MonetaryUnit(sa[0], Integer.parseInt(sa[1]));
vendList.add(vIn);
}
else if(se < x && x < e) {
String[] sa = s.split("\\(|\\)");
vIn = new VendedItem(sa[0], Integer.parseInt(sa[1]));
vendList.add(vIn);
}
else if(e < x) {
vIn = new VendingEvent(s);
vendList.add(vIn);
}
}
it = vendList.iterator();
}
public VendingInput next() {
if(list.isEmpty()) return null;
if(it.hasNext()) {
return it.next();
}
return null;
}
public VendingInput randomNext() {
return vendList.get(rand.nextInt(vendList.size()));
}
public VendingInput textExampleNext(String fileName) {
if(!input.hasNext()) return null;
String s = input.next().trim();
String s1 = s.charAt(0) + s.substring(1).toLowerCase();
for(int i = 0; i < this.vendList.size(); i++) {
if(vendList.get(i).name().equals(s1)) {
return vendList.get(i);
}
}
return null;
}
}