---------------------- <a href="http://www.itheima.com"target="blank">ASP.Net+Unity开发</a>、<a href="http://www.itheima.com"target="blank">.Net培训</a>、期待与您交流! ----------------------
交通灯管理系统
模拟实现十字路口的交通灯管理系统的逻辑,要求如下:
1、异步随机生成按照各个路线行驶的车辆。
如:
由南向而来去往北向的车辆 ---- 直行车辆
由南向而来去往东向的车辆 ---- 右转车辆
由南向而来去往西向的车辆 ---- 左转车辆
2、信号灯忽略黄灯,只考虑红灯和绿灯。
3、应考虑左转车辆控制信号灯,右转车辆不受信号灯控制。
4、具体信号灯控制逻辑与现实生活中普通交通灯控制逻辑相同,不考虑特殊情况下的控制逻辑。
注:南北向车辆与东西向车辆交替放行,同方向等待车辆应先放行直行车辆而后放行左转车辆。
5、每辆车通过路口时间为1秒(提示:可通过线程Sleep的方式模拟)。
6、随机生成车辆时间间隔以及红绿灯交换时间间隔自定,可以设置。
7、不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果
解题思路:
一、(1)由南向北的车辆——直行车辆; (2)由南向西的车辆——左转车辆; (3)由南向东的车辆——右转车辆
二、变灯:(路1)先直行在拐弯在另一条道(路2)先直行在拐弯,然后重复
三、初步对象有:灯的控制系统、汽车、路线;(1)汽车看到自己所在路线对应的路灯还要看前面是否有车;(2)看前面是否有车,注意:路是存储车辆的集合;
四、(1)路上就应该有增加车辆和减少车辆的需求;(2)但我们不要车移动的过程,而要捕捉车辆穿过路口过程(车辆增减的过程),车就应该设置为字符串(路上集合中的字符串),而不设置对象;所以对象就路,灯,灯控制系统。
注意:谁拥有数据,谁就有对外提供操作这些数据的方法;
五、灯一共有12个(右拐有灯——常绿共4个),因为数量是确定的——考虑枚举(12个实例对象)。
灯(枚举的对象:12个):
设计4个灯(有逻辑):自身变亮,对应相反也变亮;(反之变红也一样,同时下一个方向上边绿)
灯的变量有3个(相反方向的灯和下一个方向上的灯、还有灯自身的状态),共3个成员变量
右拐的灯常亮(true)
控制灯的控制器:
变量:当前的绿灯
方法:定时器——变灯用的(返回值:下一个灯)
解题步骤:
定义Load类
(1) 定义集合V(交通工具—泛型),通过构造方法”路”获取路的名字,
(2) (通过用java5线程库,以及线程池)ExecutorServicepool =Executors.NewSingleThreadExecutor(),获得的池来执行一个线程pool.execute(new Runnable(){})通过里面的run(),来不断的产生车辆(“路+车名”),可以使用Thread.sleep()里面定义随机值产生车,注意要抛异常;
(3) 定义定时器:(多线程的运行代码:把集合中的第一辆车移走(要判断灯)、过多少时间后接着移走
ScheduledExecutorService timer =Executors.newScheduledThreadPool(1))
//代码如下
package traffic.lamp;
import java.util.*;
importjava.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
importjava.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Road {
private String name;
final List vechiles = new ArrayList();
Road( String name){
this.name=name;
//创建一个线程池
ExecutorService pool = Executors.newSingleThreadExecutor();
pool.execute( new Runnable() {
public void run() {
for(int i=1;i<100;i++){
try{
Thread.sleep((newRandom().nextInt(10)+1)*1000);
}
catch (InterruptedExceptione) {
e.printStackTrace();
}
vechiles.add(Road.this.name+"-"+i);
}
}
});
ScheduledExecutorService timer =Executors.newScheduledThreadPool(1);
timer.scheduleAtFixedRate(
new Runnable() {
public void run(){
if(vechiles.size()>0){
if(Lamp.valueOf(Road.this.name).lighted()){
System.out.println(vechiles.remove(0)+"正在通过...");
}
}
}
},
1,
1,
TimeUnit.SECONDS);
}
}
建立灯类(枚举的方法)
(1)定义构造方法有3个参数(对应的灯、下一个灯,灯开始是否为亮的);12个灯列表
(2)判断灯是否变绿,额外还有3个方法 ”灯变绿” 或 ”灯变红” 以及 ”下一个灯” ;
package traffic.lamp;
public enum Lamp {
S2N(false,"N2S","S2W"),S2W(false,"N2E","E2W"),E2W(false,"W2E","E2S"),E2S(false,"W2N","S2N"),
N2S(false,null,null),N2E(false,null,null),W2E(false,null,null),W2N(false,null,null),
S2E(true,null,null),E2N(true,null,null),N2W(true,null,null),W2S(true,null,null);
private boolean lighted;
private String oppLamp;
private String nextLamp;
private Lamp(boolean lighted,String oppoLamp,String nextLamp){
this.lighted=lighted;
this.oppLamp=oppoLamp;
this.nextLamp=nextLamp;
}
public boolean lighted(){
return lighted;
}
public boolean isLighted(){
this.lighted=true;
if(oppLamp!=null){
Lamp.valueOf(oppLamp).isLighted();
}
return lighted;
}
public Lamp isDarked(){
this.lighted=false;
if(nextLamp!=null){
Lamp.valueOf(nextLamp).isLighted();
System.out.println("绿灯从"+name()+"切换为"+Lamp.valueOf(nextLamp));
}
return Lamp.valueOf(nextLamp);
}
}
建立控灯系统类
建立成员变量控灯,并将其进行构造函数初始化,通过线程池以及多线程获取run()
package traffic.lamp;
import java.util.concurrent.Executors;
importjava.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class LampController {
private Lamp currentLamp;
public LampController() {
currentLamp=Lamp.S2N;
currentLamp.isLighted();
ScheduledExecutorService timer =Executors.newScheduledThreadPool(1);
timer.scheduleAtFixedRate(
new Runnable() {
public void run() {
currentLamp=currentLamp.isDarked();
}
},
10,
10,
TimeUnit.SECONDS);
}
}
主函数
package traffic.lamp;
public class MainTest {
public static void main(String[] args) {
String[] direction ={"S2N","S2W","E2W","E2S","N2S","N2E","W2E","W2N","S2E","E2N","N2W","W2S"};
for(int i=0;i<direction.length;i++){ new Road(direction[i]);
}
new LampController();
}
}
额外面向对象的知识:
1、 熟悉面向对象:人在黑板画圆person blackboard circle(3个对象);——圆 关门的动作——门
列车司机停车——车 售货员统计票据金额:——票据 减少汽车的方法——路
2、 球过绳子:对象有小球(有移动的方法,在构造方法中将绳子传给小球);绳子(为球的移动提供了方法即nextPoint()——获取摸一个点的下一个坐标,还有2个点 )
3、 2块石头磨成一把石刀,石刀可以砍树,木材可以做成椅子:Stone—StoneKnife—tree—material—chair
StoneKnife = KnifePactory.creatKnife(Stone first,Stonesecond)//2块石头变成”一把”刀,该方法接受的应该是石头
Material = StoneKnife.cut(tree) //刀有一个方法,变量是tree
Chair = ChairFactory.makeChair(Material)//椅子加工有一个方法,变量是材料
---------------------- <a href="http://www.itheima.com"target="blank">ASP.Net+Unity开发</a>、<a href="http://www.itheima.com"target="blank">.Net培训</a>、期待与您交流! ----------------------