您的位置:首页 > 职场人生

【黑马程序员】java 7k面试题--交通灯管理系统

2013-12-04 07:36 316 查看
---------------------- <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>、期待与您交流!
----------------------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: