---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------
一、交通灯题目
模拟生活中的红绿灯控制系统。
1.按照现实生活中,汽车按照交通指示灯选择自己所走的路线行驶。
比如:
由南向北方向绿灯,车辆可以由南向北行驶。----直行车辆
由南向西的方向绿灯,车辆可以由南向西行驶。-----左转弯车辆
由南向东的方向(该方向考虑设置为常绿灯),车辆可以由由南向东行驶。----右转弯的车辆
........
2.交通信号灯,就只考虑红灯和绿灯吧,本来想考虑加上黄灯,没有做成功
3.交通指示灯只设计了左转弯和直行路线受交通灯控制切换,右转向灯设计为常绿灯。
4.在12条路线中:
1.4条右转弯路线为常绿灯,不考虑其他情况
2.南北路线和东西路线,受交通灯控制,进行切换交替车辆执行
3.将路看成一个集合,通过随机生成的时间间隔随机有车辆进入到路线当中
通过定时器类,固定频率的时间间隔,绿灯指示车辆驶离所在路线当中的集合
4.交通灯的时间切换可以通过定义一个控制其的类控制,应用定时器实现
二.交通路线分析:
1、对车辆所有的路线分析下图:
分析:
a、总共12条路线,每条路线作为一个对象存在。
b、根据分析,没条路线都有一个灯控制,12个灯
c、其中4条右转方向的线路,为常亮灯,不受其他线路的影响。而其他8条线路有着反方向对应的关系,
可以两两对应,分成4组:上图1号路线对应的是N2S路线为一组
2号S2W路线对应的是N2E路线为一组.....这样可以分为4组
2、根据面向对象的分析设计
a、分析设计成3个对象,交通灯、交通灯控制器(控制灯的切换)、路线(汽车在路线中)。
详细:在路线对象构造函数中,随机时间间隔生成汽车,存入线路集合中,在现实生活中,我们理解的是汽车看到红灯
就行驶过红绿灯,在这里其实不是,而是汽车要行驶,必须问路这个对象,在绿灯的情况要看路前面有没有车。
在设计中,我们只考虑汽车增加和减少车辆这个结果,在路线类中对外提供增加和减少的方法。
b、路线对象:每条路线可以通过集合存储汽车,通过线程池线程sleep()、随机类随机时间间隔来随机生成车辆增加进集合
且路线中还需要通过定时器思想,固定频率的在绿灯情况下增加和减少车辆。
1、设计一个Road类表示路线,每个Road对象代表一条路线,总共12条路线对象
2、每条路线上随机增加新的车辆,通过集合临时储存。
3、每条路线没过一秒检查,路线上的灯是否为绿灯,如果是,就将本路线集合中的第一辆车去除,表示该车辆在绿灯时过的红绿灯
c、对交通灯对象和控制器对象的设计思路:
1、设计一个Lamp表示一个指示灯,每个指示灯在本系统中红绿状态,每个指示灯
要提供变红、变绿的方法,并且可以返回自己的当前状态
2、路线总共12条,所以需要12个指示灯对象来指示。考虑到右转弯的路线不受其他路线影响,
可以将其和指示灯设置为常绿灯,不变红状态。
3、剩下的8条路线两两对应,可以设计成4组路线,在代码中的体现:
比如:第一组:(当前灯)东——>往西路线为绿灯时,
对应相反方向的路线(对应反方向的灯):西——>东路线同时为绿灯
第二组:左转弯的路线(下一个灯):东——>往南路线为绿;
左转弯的路线(下一个灯):西——>往北方向路线;
第三组:。。。。。。这样进行切换
Lamp类中当前灯的状态,需要变量记住对应反方向灯和下一个灯。
4、通过对12个指示灯的分析,可以采用枚举(enum)设计,确定112个灯的对象为固定的
5、交通灯控制器LampController类,定时器实现灯的切换
三、代码实现
1、路对象Road类的代码实现:
每条路线对象,需要一个name属性,路线中需要一个集合(vehicles)来存储车辆的集合
在Road类中在构造方法中通过线程每隔sleep()向集合中增加车辆,时间通过随机数生成
在Road对象构造函数中,通过定时器,每隔多长时间判断该路线是否为绿灯,通过移除第一辆车来表示
练习代码:
package cn.the_traffic;
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 {
protected static final boolean lighted = false;
List<String> car=new ArrayList<String>();//创建一个集合用于存储
private String name=null; //路线的属性name
public Road(String name){
this.name=name;
//开启线程池,
ExecutorService thread =Executors.newSingleThreadExecutor();
thread.execute(new Runnable(){
public void run(){
for(int i=0;i<1000;i++){
try {
//随机10秒数,等待
Thread.sleep((new Random().nextInt(10)+1)*1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//向集合中添加汽车
car.add(Road.this.name+":----------"+i);
}
}
});
//定时器,每10秒钟,进行一次判断,灯(lighted)是否为true,为真时,汽车离开
//该单条线程步骤只是在操作集合中的汽车去除操作
ScheduledExecutorService time=Executors.newScheduledThreadPool(1);
time.scheduleAtFixedRate(
new Runnable(){
public void run(){
if(car.size()>0){
boolean lighted = Lamp.valueOf(Road.this.name).isLighted();
if(lighted){
System.out.println("绿灯亮了:"+car.remove(0)+"车驶出路口!!!");
}
}
}
},
1,
1,
TimeUnit.SECONDS);
}
}
2、Lamp类灯对象:
1.通过枚举来定义12个固定的指示灯对象。枚举中的元素就是他的本类对象;
2.每个Lamp对象中的状态用lighted变量表示,用oppositeLampName变量表示对应反方向的灯,在用一个
nextLampLamp变量来表示下一个变亮的灯。
3.提供Lamp变亮变黑的方法:light()和blackOut()
练习代码:
package cn.the_traffic;
public enum Lamp {
S2N("N2S","S2W",false),S2W("N2E","E2W",false),E2W("W2E","E2S",false),E2S("W2N","S2N",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 boolean lighted; //当前灯的状态,是否为绿
private String opposite; //与当前灯相反方向的同为绿的灯
private String next;//当前灯变红时,下个绿的灯
private Lamp(String opposite,String next,boolean lighted){
this.opposite=opposite;
this.next=next;
this.lighted=lighted;
}
public boolean isLighted(){ //提供一个判断是否为亮(绿)的方法
return lighted;
}
public void light(){
this.lighted=true;
if(opposite!=null){//为造成死循环,只将一方拥有反方向的灯
//枚举中静态方法,接收一个字符串,返回它对应的对象
Lamp.valueOf(opposite).light(); //将对应的反方向的灯变绿
}
System.out.println(name()+"路线为绿灯;下面应该有6个方向的车通过");
}
// 某个灯变红时,对应方向的灯也要变红,并且下一个方向的灯要变绿 @return 下一个要变绿的灯
public Lamp blackOut(){
this.lighted=false; //当前灯变红,对应方向的灯也变红
if(opposite!=null){
Lamp.valueOf(opposite).blackOut();
}
//当前灯变红的同时,将下一个灯变绿
//变将下一个变绿的灯返回
Lamp nextLamp=null;
if(next!=null){
nextLamp=Lamp.valueOf(next);
System.out.println("绿灯"+name()+"--------------------------切换"+next);
nextLamp.light();
}
return nextLamp;
}
}
3、交通灯控制器LampController类
练习代码:
package cn.the_traffic;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class LampContorller {
private Lamp currentLamp ; //当前灯为绿
public LampContorller(){
currentLamp=Lamp.S2N;//将第一个灯赋值给控制器
currentLamp.light(); //状态为绿灯
//定义一个定时器,首次隔7秒切换灯的状态,第二次每隔5秒切换
ScheduledExecutorService timer=Executors.newScheduledThreadPool(1);
timer.scheduleAtFixedRate(
new Runnable(){
public void run(){
//将下一个灯切换成当前灯
currentLamp=currentLamp.blackOut();
}
},
7,
5,
TimeUnit.SECONDS);
}
}
4、启动交通灯系统的类MainClass类:
练习代码:
package cn.the_traffic;
public class MainClass {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//定义一个数组,将12条路线存入数组
String[] directions=new String[]{
"S2N","S2W","E2W","E2S","N2S","N2E","W2E","W2N","S2E","E2N","N2W","W2S"
};
//通过for循环创建路线对象
for(int i=0;i<directions.length;i++){
new Road(directions[i]);
}
//创建交通灯控制器对象
new LampContorller();
}
}
---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------