交通灯程序设计
1.画图考虑四条线路的设计,对应的可以先不考虑opposite。,所以是直行的两个线路跟转弯的两个线路。
2.线路是绿灯且问路线起前方是否有车。谁拥有数据,谁就提供使用数据的方法。所以要有路上车辆的集合,并且提供增加和减少车辆的方法。这里只是捕捉车辆通过路口的过程,所以用字符串代表每辆车,不需要创建车的对象。
3.目前最大的困难是拿到问题时理不清各个类之间的变量关系,有一部分原因是因为之前写代码都是在一个java文件中完成的,现在突然要在几个文件中来完成似乎很难分清楚到底在Road类中要定义哪些变量,在Lamp类中都要定义哪些变量,而又用到了Road类中的哪些变量跟方法。这样的困难似乎还是没有对需求分析透彻,同时也在于实际解决问题的经验不足,确切来讲现在只是把教程中的部分练习完成了而已。所以交通灯这个需求没个三遍搞不定也似乎很正常的吧。
就按照基础总结中的步骤一步步来实现,熟练之后也必然轻车熟路
1,明确需求。我要做什么?
2,分析思路。我要怎么做?1,2,3。
3,确定步骤。每一个思路部分用到哪些语句,方法,和对象。
4,代码实现。用具体的java语言代码把思路体现出来。
1.需求交通灯,只有红绿灯,不考虑黄灯,右转方向不控制(可以理解为一直是绿灯),同方向的应先放行直行的,然后放行转弯的(这里就只针对左转了)一共12条线路,4个右转的可以不考虑,剩下的去掉对应方向的剩下四条线路,用当前位置的来控制对应位置的灯,每辆车通过时间为1秒
2. 1.创建线路的类,2.创建灯的类,3.创建控制系统的类 4.主函数的类
3.1 1.线路上用ArrayList集合模拟出车的集合,并随机产生车辆,车辆就用字符串来表示,初始化时传递name命名多条线路-->多线程Executors.newSingleThreadExecutor()方法,在参数上用Runnable的匿名内部实现子类,复写run方法,产生随机车辆。2.创建包含线程的定时器Executors.newScheduledThreadPool(1),在绿灯的情况下每隔一秒放行一辆车
3.2 1.灯用枚举构成,一共是12个,4个有逻辑。初始化时有三个属性,分别是opposite,next,lighted,即对面的灯,下一个灯以及灯的状态,isLighted方法,返回灯的状态值,light方法,将灯的状态赋值为true,判断opposite属性如果非null,用枚举的方法valueOf把对面的灯打开。blackOut方法,将状态赋值false,判断对面非空,使用valueOf将对面灯关闭,定义Lamp类型变量nextLamp赋值null,如果next属性非空,则nextLamp赋值next的那个灯,并将其点亮,最后方法返回nextLamp
3.3定义控制器,成员变量currentLamp,在初始化时将某个有逻辑的灯赋值给currentLamp并点亮,定义一个计时器每隔一段时间运行线程中的方法(将currentLamp灭掉并将返回值赋给currentLamp)
问题:1.为什么那些计时器和产生汽车的线程都要放在构造函数中? 2.主函数中产生车辆的方法怎么是那样的
package com.itheima;
public class MainClass {
/**
* @param args
*/
public static void main(String[] args) {
String[] directions = new String[]{
"S2N","S2W","E2W","E2S","N2S","N2E","W2E","W2N","S2E","E2N","N2W","W2S"};
for(int i=0;i<directions.length;i++){
new Road(directions[i]);
}
new LampController();
}
}
package com.itheima;
public enum Lamp {
S2N("N2S","S2W",false),S2W("N2E","E2W",false),E2W("W2E","E2S",false),E2S("W2N","N2S",false),
N2S(null,null,false),N2E(null,null,false),W2E(null,null,false),W2N(null,null,false),
S2E(null,null,true),E2N(null,null,true),N2W(null,null,true),W2S(null,null,true);
private Lamp(String opposite,String next,boolean lighted){
this.opposite = opposite;
this.next = next;
this.lighted = lighted;
}
//与当前灯同时为绿的对应方向
private String opposite;
//当前灯为红下一个变绿的灯的方向
private String next;
//当前灯是否为绿的状态
private boolean lighted;
public boolean isLighted(){
return lighted;
}
public void light(){
this.lighted = true;
if(opposite != null){
Lamp.valueOf(opposite).light();
}
System.out.println(name() + " lamp is green,下面总共应该有6个方向能看到汽车穿过!");
}
public Lamp blackOut(){
this.lighted = false;
if(opposite != null){
Lamp.valueOf(opposite).blackOut();
}
Lamp nextLamp = null;
if(next != null){
nextLamp = Lamp.valueOf(next);
nextLamp.light();
}
return nextLamp;
}
}
package com.itheima;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class LampController {
private Lamp currentLamp;
public LampController(){
currentLamp = Lamp.S2N;
currentLamp.light();
ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
timer.scheduleAtFixedRate(new Runnable(){
@Override
public void run() {
System.out.println("来啊");
currentLamp = currentLamp.blackOut();
}
},
10,
10,
TimeUnit.SECONDS);
}
}
package com.itheima;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Road {
private List<String> vechicles = new ArrayList<String>();
private String name;
public Road(String name){
this.name=name;
//模拟线路上的车辆
ExecutorService pool = Executors.newSingleThreadExecutor();
pool.execute(new Runnable(){
@Override
public void run() {
for(int i=1;i<1000;i++){
try {
Thread.sleep((new Random().nextInt(10) + 1) *1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
vechicles.add(Road.this.name+"_"+i);
}
}
});
//每隔一秒检查对应的灯是否为绿,是则放行一辆车
ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
timer.scheduleAtFixedRate(new Runnable(){
@Override
public void run() {
if(vechicles.size()>0){
boolean lighted = Lamp.valueOf(Road.this.name).isLighted();
if(lighted){
System.out.println(vechicles.remove(0)+"is traveling!");
}
}
}
},
1,
1,
TimeUnit.SECONDS);
}
}