我不用打代码:)Exercise 42
//: c09:E42_GreenhouseLinkedList.java
//+M java E42_GreenhouseLinkedList
/****************** Exercise 42 *****************
* In Chapter 8, locate the
* GreenhouseControls.java example, which
* consists of three files. In Controller.java,
* the class EventSet is just a container. Change
* the code to use a LinkedList instead of an
* EventSet. This will require more than just
* replacing EventSet with LinkedList; you'll
* also need to use an Iterator to cycle through
* the set of events.
***********************************************/
import java.util.*;abstract class Event {
private long evtTime;
public Event(long eventTime) {
evtTime = eventTime;
}
public boolean ready() {
return System.currentTimeMillis() >= evtTime;
}
abstract public void action();
abstract public String description();
public String toString() {
return "Event: " + description();
}
}class Controller {
private LinkedList es = new LinkedList();
public void addEvent(Event c) {
System.out.println("Adding " + c);
es.add(c);
}
// This wouldn't work:
// public void run() {
// ListIterator it = es.listIterator();
// while(es.size() != 0) {
// while(it.hasNext()) {
// Event e = (Event)it.next();
// System.out.println("Testing " + e);
// if(e.ready()) {
// System.out.println("Running " + e);
// e.action();
// System.out.println(e.description());
// int prevIndex = it.previousIndex();
// // To prevent concurrent modification:
// LinkedList tmp = new LinkedList(es);
// tmp.remove(e);
// es = tmp;
// it = es.listIterator();
// }
// }
// }
// }
public void run() {
int index = 0;
while(es.size() != 0) {
Event e = (Event)es.get(index);
if(e.ready()) {
e.action();
System.out.println(e.description());
es.remove(index);
}
index = (index + 1) % es.size();
}
}
}public class E42_GreenhouseLinkedList
extends Controller {
private boolean light = false;
private boolean water = false;
private String thermostat = "Day";
private class LightOn extends Event {
public LightOn(long eventTime) {
super(eventTime);
}
public void action() {
// Put hardware control code here to
// physically turn on the light.
light = true;
}
public String description() {
return "Light is on";
}
}
private class LightOff extends Event {
public LightOff(long eventTime) {
super(eventTime);
}
public void action() {
// Put hardware control code here to
// physically turn off the light.
light = false;
}
public String description() {
return "Light is off";
}
}
private class WaterOn extends Event {
public WaterOn(long eventTime) {
super(eventTime);
}
public void action() {
// Put hardware control code here
water = true;
}
public String description() {
return "Greenhouse water is on";
}
}
private class WaterOff extends Event {
public WaterOff(long eventTime) {
super(eventTime);
}
public void action() {
// Put hardware control code here
water = false;
}
public String description() {
return "Greenhouse water is off";
}
}
private class ThermostatNight extends Event {
public ThermostatNight(long eventTime) {
super(eventTime);
}
public void action() {
// Put hardware control code here
thermostat = "Night";
}
public String description() {
return "Thermostat on night setting";
}
}
private class ThermostatDay extends Event {
public ThermostatDay(long eventTime) {
super(eventTime);
}
public void action() {
// Put hardware control code here
thermostat = "Day";
}
public String description() {
return "Thermostat on day setting";
}
}
// An example of an action() that inserts a
// new one of itself into the event list:
private int rings;
private class Bell extends Event {
public Bell(long eventTime) {
super(eventTime);
}
public void action() {
// Ring every 2 seconds, 'rings' times:
System.out.println("Bing!");
if(--rings > 0)
addEvent(new Bell(
System.currentTimeMillis() + 200));
}
public String description() {
return "Ring bell";
}
}
static int iterations = 3;
private class Restart extends Event {
public Restart(long eventTime) {
super(eventTime);
}
public void action() {
if(--iterations <= 0) System.exit(0);
long tm = System.currentTimeMillis();
// Instead of hard-wiring, you could parse
// configuration information from a text
// file here:
rings = 5;
addEvent(new ThermostatNight(tm));
addEvent(new LightOn(tm + 100));
addEvent(new LightOff(tm + 200));
addEvent(new WaterOn(tm + 300));
addEvent(new WaterOff(tm + 800));
addEvent(new Bell(tm + 900));
addEvent(new ThermostatDay(tm + 1000));
// Can even add a Restart object!
addEvent(new Restart(tm + 2000));
}
public String description() {
return "Restarting system";
}
}
public static void main(String[] args) {
E42_GreenhouseLinkedList gc =
new E42_GreenhouseLinkedList();
long tm = System.currentTimeMillis();
gc.addEvent(gc.new Restart(tm));
gc.run();
}
} ///:~
This one was a little tricky. Initially, it seems like a straightforward cut-and-paste, eliminating the handmade container class by replacing it with LinkedList. As you can see in the commented-out area, using an iterator became problematic, first because if you use the iterator to modify what you’re currently iterating through, you get a ConcurrentModificationException. This was “solved” by making a copy of the list before modifying, then removing the item and replacing the old list with the new one, then getting an iterator to the new list. However, this solution tended to start working, then hang.
There’s probably a way to get the iterator solution to work correctly, but I fell back to “the simplest thing that could possibly work” and realized that it would be simpler and more reliable just to manipulate the container directly rather than using an iterator.
In Restart.action( ) I’ve added a test to limit the number of repetitions so that the program completes in a short time.
//: c09:E42_GreenhouseLinkedList.java
//+M java E42_GreenhouseLinkedList
/****************** Exercise 42 *****************
* In Chapter 8, locate the
* GreenhouseControls.java example, which
* consists of three files. In Controller.java,
* the class EventSet is just a container. Change
* the code to use a LinkedList instead of an
* EventSet. This will require more than just
* replacing EventSet with LinkedList; you'll
* also need to use an Iterator to cycle through
* the set of events.
***********************************************/
import java.util.*;abstract class Event {
private long evtTime;
public Event(long eventTime) {
evtTime = eventTime;
}
public boolean ready() {
return System.currentTimeMillis() >= evtTime;
}
abstract public void action();
abstract public String description();
public String toString() {
return "Event: " + description();
}
}class Controller {
private LinkedList es = new LinkedList();
public void addEvent(Event c) {
System.out.println("Adding " + c);
es.add(c);
}
// This wouldn't work:
// public void run() {
// ListIterator it = es.listIterator();
// while(es.size() != 0) {
// while(it.hasNext()) {
// Event e = (Event)it.next();
// System.out.println("Testing " + e);
// if(e.ready()) {
// System.out.println("Running " + e);
// e.action();
// System.out.println(e.description());
// int prevIndex = it.previousIndex();
// // To prevent concurrent modification:
// LinkedList tmp = new LinkedList(es);
// tmp.remove(e);
// es = tmp;
// it = es.listIterator();
// }
// }
// }
// }
public void run() {
int index = 0;
while(es.size() != 0) {
Event e = (Event)es.get(index);
if(e.ready()) {
e.action();
System.out.println(e.description());
es.remove(index);
}
index = (index + 1) % es.size();
}
}
}public class E42_GreenhouseLinkedList
extends Controller {
private boolean light = false;
private boolean water = false;
private String thermostat = "Day";
private class LightOn extends Event {
public LightOn(long eventTime) {
super(eventTime);
}
public void action() {
// Put hardware control code here to
// physically turn on the light.
light = true;
}
public String description() {
return "Light is on";
}
}
private class LightOff extends Event {
public LightOff(long eventTime) {
super(eventTime);
}
public void action() {
// Put hardware control code here to
// physically turn off the light.
light = false;
}
public String description() {
return "Light is off";
}
}
private class WaterOn extends Event {
public WaterOn(long eventTime) {
super(eventTime);
}
public void action() {
// Put hardware control code here
water = true;
}
public String description() {
return "Greenhouse water is on";
}
}
private class WaterOff extends Event {
public WaterOff(long eventTime) {
super(eventTime);
}
public void action() {
// Put hardware control code here
water = false;
}
public String description() {
return "Greenhouse water is off";
}
}
private class ThermostatNight extends Event {
public ThermostatNight(long eventTime) {
super(eventTime);
}
public void action() {
// Put hardware control code here
thermostat = "Night";
}
public String description() {
return "Thermostat on night setting";
}
}
private class ThermostatDay extends Event {
public ThermostatDay(long eventTime) {
super(eventTime);
}
public void action() {
// Put hardware control code here
thermostat = "Day";
}
public String description() {
return "Thermostat on day setting";
}
}
// An example of an action() that inserts a
// new one of itself into the event list:
private int rings;
private class Bell extends Event {
public Bell(long eventTime) {
super(eventTime);
}
public void action() {
// Ring every 2 seconds, 'rings' times:
System.out.println("Bing!");
if(--rings > 0)
addEvent(new Bell(
System.currentTimeMillis() + 200));
}
public String description() {
return "Ring bell";
}
}
static int iterations = 3;
private class Restart extends Event {
public Restart(long eventTime) {
super(eventTime);
}
public void action() {
if(--iterations <= 0) System.exit(0);
long tm = System.currentTimeMillis();
// Instead of hard-wiring, you could parse
// configuration information from a text
// file here:
rings = 5;
addEvent(new ThermostatNight(tm));
addEvent(new LightOn(tm + 100));
addEvent(new LightOff(tm + 200));
addEvent(new WaterOn(tm + 300));
addEvent(new WaterOff(tm + 800));
addEvent(new Bell(tm + 900));
addEvent(new ThermostatDay(tm + 1000));
// Can even add a Restart object!
addEvent(new Restart(tm + 2000));
}
public String description() {
return "Restarting system";
}
}
public static void main(String[] args) {
E42_GreenhouseLinkedList gc =
new E42_GreenhouseLinkedList();
long tm = System.currentTimeMillis();
gc.addEvent(gc.new Restart(tm));
gc.run();
}
} ///:~
This one was a little tricky. Initially, it seems like a straightforward cut-and-paste, eliminating the handmade container class by replacing it with LinkedList. As you can see in the commented-out area, using an iterator became problematic, first because if you use the iterator to modify what you’re currently iterating through, you get a ConcurrentModificationException. This was “solved” by making a copy of the list before modifying, then removing the item and replacing the old list with the new one, then getting an iterator to the new list. However, this solution tended to start working, then hang.
There’s probably a way to get the iterator solution to work correctly, but I fell back to “the simplest thing that could possibly work” and realized that it would be simpler and more reliable just to manipulate the container directly rather than using an iterator.
In Restart.action( ) I’ve added a test to limit the number of repetitions so that the program completes in a short time.
解决方案 »
- 字节输入输出流读写文件
- 如何用eclipse导入外来项目?
- 请教 StringBuffer 使用问题,在线等,请指导
- java联机小游戏,做了一半,socket没学,联机不怎么会,求指导一个玩家控制点,一个玩家控制蛇,在电脑的局域网实现
- Log4j配置问题,急、急、急。
- httpclient
- 课程设计,马上要交了,我还没搞定,HELP !!!! (星期一发帖,明天晚结贴)急急急急急急急急急急急!!!
- JCertify最新的版本是多少?
- 用什么集合类存储成对的信息最方便双向的检索?
- 我之前用小脚本写的能查询出来,完事改成el表达式,查询不了
- 怎样改变窗体的风格?
- 急:Java访问MySQL数据库的环境设置和几个问题
import java.util.*;
abstract class Event {
private long evtTime;
public Event(long eventTime) {
evtTime = eventTime;
}
public boolean ready() {
return System.currentTimeMillis() >= evtTime;
}
abstract public void action();
abstract public String description();
}
class Controller {
private LinkedList el = new LinkedList();
public void addEvent(Event c) {
el.add(c);
}
public void run() {
/*
How can I use an Iterator to do this?
Iterator it = el.iterator();
while(it.hasNext()) {
Event e = (Event) it.next();
if(e.ready()) {
e.action();
System.out.println(e.description());
it.remove();
}
}
*/
}
}
}
}
public class E42_GreenhouseControls extends Controller {
private boolean light = false;
private boolean water = false;
private String thermostat = "Day";
private class LightOn extends Event {
public LightOn(long eventTime) {
super(eventTime);
}
public void action() {
light = true;
}
public String description() {
return "Light is on";
}
}
private class LightOff extends Event {
public LightOff(long eventTime) {
super(eventTime);
}
public void action() {
light = false;
}
public String description() {
return "Light is off";
}
}
private class WaterOn extends Event {
public WaterOn(long eventTime) {
super(eventTime);
}
public void action() {
water=true;
}
public String description() {
return "Greenhouse water is on";
}
}
private class WaterOff extends Event {
public WaterOff(long eventTime) {
super(eventTime);
}
public void action() {
water=false;
}
public String description() {
return "Greenhouse water is off";
}
}
private class ThermostatNight extends Event {
public ThermostatNight(long eventTime) {
super(eventTime);
}
public void action() {
thermostat="Night";
}
public String description() {
return "Thermostat on night setting";
}
}
private class ThermostatDay extends Event {
public ThermostatDay(long eventTime) {
super(eventTime);
}
public void action() {
thermostat="Day";
}
public String description() {
return "Thermostat on day setting";
}
}
private int rings;
private class Bell extends Event {
public Bell(long eventTime) {
super(eventTime);
}
public void action() {
System.out.println("Bing!");
if(--rings>0) {
addEvent(new Bell(System.currentTimeMillis()+2000));
}
}
public String description() {
return "Ring bell";
}
}
private class Restart extends Event {
public Restart(long eventTime) {
super(eventTime);
}
public void action() {
long tm=System.currentTimeMillis();
rings=5;
addEvent(new ThermostatNight(tm));
addEvent(new LightOn(tm+1000));
addEvent(new LightOff(tm+2000));
addEvent(new WaterOn(tm+3000));
addEvent(new WaterOff(tm+8000));
addEvent(new Bell(tm+9000));
addEvent(new ThermostatDay(tm+10000));
addEvent(new Restart(tm+20000));
}
public String description() {
return "Restarting system";
}
}
public static void main(String[] args) {
E42_GreenhouseControls gc=new E42_GreenhouseControls();
long tm=System.currentTimeMillis();
gc.addEvent(gc.new Restart(tm));
gc.run();
}
}