黑马程序员-java学习笔记之交通灯管理系统
2014-03-21 12:51
337 查看
------- android培训、java培训、期待与您交流!-------
1.需求
模拟实现十字路口的交通灯管理系统逻辑,具体需求如下:异步随机生成按照各个路线行驶的车辆。
例如:
由南向而来去往北向的车辆 ---- 直行车辆
由西向而来去往南向的车辆 ---- 右转车辆
由东向而来去往南向的车辆 ---- 左转车辆。。。
信号灯忽略黄灯,只考虑红灯和绿灯。
应考虑左转车辆控制信号灯,右转车辆不受信号灯控制。
具体信号灯控制逻辑与现实生活中普通交通灯控制逻辑相同,不考虑特殊情况下的控制逻辑。
注:南北向车辆与东西向车辆交替放行,同方向等待车辆应先放行直行车辆而后放行左转车辆。
每辆车通过路口时间为1秒(提示:可通过线程Sleep的方式模拟)。
随机生成车辆时间间隔以及红绿灯交换时间间隔自定,可以设置。
不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。
2.需求分析
首先画一个十字路口的图片,把所有的路线图在图上标注出来:上面一共有十二条线路,在平时生活中,右拐弯是一直通行的,在此假设右拐弯的都是绿灯。然后还有八条线路,剩下的这八条线路的灯都是成对亮的,可以归为4组,东-西两组,南-北两组,所以,程序只需考虑图中标注了数字号的4条路线的控制灯的切换顺序,这4条路线相反方向的路线的控制灯跟随这4条路线切换,不必额外考虑。
我们初步设想一下有哪些对象:红绿灯,红绿灯的控制系统,汽车,路线。汽车看到自己所在路线对应的灯绿了就穿过路口吗?不是,还需要看其前面是否有车,看前面是否有车,该问哪个对象呢?该问路,路中存储着车辆的集合,显然路上就应该有增加车辆和减少车辆的方法了。再看题目,我们这里并不要体现车辆移动的过程,只是捕捉出车辆穿过路口的过程,也就是捕捉路上减少一辆车的过程,所以,这个车并不需要单独设计成为一个对象,用一个字符串表示就可以了。
所以系统中存在的对象应该有12个路灯对象,十二个路线对象,和一个路灯控制器对象。
2.类的编写
Road类:
每一个Road对象都有名称,定义私有变量:路的名字。每条路上都有车,车必须有顺序的添加和移除:用ArrayList来保存车。
每一个车的名字起名字。路线的名字 + 车的编号。
每创建一条路线,就有了路线的名字:构造方法要接受名称参数。
创建车辆:假设每一秒种,这条路上就出现有一辆车,所以要在构造方法内部不停的创建车,利用for循环来创建。
但是不能一次性创建1000辆,不然一瞬间有1000辆是不现实的,利用随机数,Thread.sleep随机休息一会再生成车。
但是:对象创建期间,如果Thread.Sleep,对象不返回的,这么对象根本创建不出来。利用线程即可解决,线程在方法结束之后还可以运行!
所以可以在构造方法内部使用线程技术进行生成车辆。利用java5中提供的线程池来操作线程,
在每一个线程中利用for循环生成车辆,线程睡眠一个随机数。希望一到10秒随机数内创建一辆车。Random.nextInt(10)+1 * 1000,一秒到十秒了。
移走车辆:车每过一秒,去看自己灯是否是绿的,是绿的就要把第一个车移走。利用定时器。利用Executors.newScheduledThreadPool(1)调度池。返回ScheduleExecutorService.,timer。利用固定频率定时器
定时器传入一个Runnable任务,一个初始化延迟时间,一个频率,一个时间单元。每过一秒就会去执行Runnable任务。
检查当前路的灯是否为绿,检查是否有车,如果有车,如果灯是绿的,则让前面的车开走。移除并打印。
道路的最终代码:
/** * 道路类:可以在1~10S内随机的生成车辆。并可以通过路口。 * @author real * */ public class Road { //List用来保存道路上的车辆 private List<String> vehicle = new ArrayList<String>(); //道路的名称 private String name; //创建Road时必须传入路名 public Road(String name) { //设置道路名为传入的名称 this.name = name; //创建一个单线程,生成车辆 ExecutorService pool = Executors.newSingleThreadExecutor(); //线程来执行任务 pool.execute(new Runnable(){ @Override public void run() { for(int i = 0; i < 1000; i++) { try { //随机休息1~10s Thread.sleep((new Random().nextInt(10) + 1) * 1000); //访问外部类的变量,用外部类的类名.this.变量名 vehicle.add(Road.this.name + "::" + i); } catch (InterruptedException e) { e.printStackTrace(); } } }}); //生成一个定时器线程池 ScheduledExecutorService timer = Executors.newScheduledThreadPool(1); //定时器调度,并且以固定频率执行任务 timer.scheduleAtFixedRate( new Runnable(){ @Override public void run() { //查看自己的灯是否是绿的,如果是绿的,则把车移动走 Lamp lamp = Lamp.valueOf(Road.this.name); if(lamp.isLighted()) { //如果道路上有车,则让车通过。 if(!vehicle.isEmpty()) { System.out.println(vehicle.remove(0) + " 通过路口!"); } } } }, 1, 1, TimeUnit.SECONDS); } }
Lamp类:
在交通灯中一共有十二个灯,而且数量时固定的。在程序的其他地方要根据灯的名称就可以获得对应的灯的实例对象。
综合这些因素,将Lamp类用java5中的枚举形式定义更为简单。
每个Lamp对象中的亮黑状态用lighted变量表示,选用S2N、S2W、E2W、E2N这四个方向上的Lamp对象依次轮询变亮。
Lamp对象中还要有一个opposite变量来表示它们相反方向的。
再用一个next变量来表示此灯变亮后的下一个变亮的灯。
这三个变量用构造方法的形式进行赋值,因为枚举元素必须在定义之后引用,所以无法再构造方法中彼此相互引用,所以,相反方向和下一个方向的灯用字符串形式表示。
增加让Lamp变亮和变黑的方法:light和black,对于S2N、S2W、E2W、E2N这四个方向上的Lamp对象,这两个方法内部要让相反方向的灯随之变亮和变黑,black方法还要让下一个灯变亮,同时要返回下一个亮着的灯给道路使用。
除了S2N、S2W、E2W、E2N这四个方向上的Lamp对象之外,其他方向上的Lamp对象的next和opposite属性设置为null即可。
并且S2N、S2W、E2W、E2N这四个方向上的Lamp对象的next和opposite属性必须设置为null,如果不为null,则在点亮灯时,会一直点亮反方向的灯,会一直死循环下去了。
右拐方向的灯一直为亮的,且没有相反方向的和下一个等。所以灯控系统实际控制的就是S2N、S2W、E2W、E2N这四个方向的灯。其对应的四个灯也是控制这四个灯时对应的控制的。
Lamp类的源代码:
/** * 灯的枚举。一共有十二个灯,其中,四个执行,四个左拐,四个右拐。 * @author real * */ public enum Lamp { /** * S:南,N:北。W:西.E:东 * 南-北:S2N,南-西:S2W.东-西:E2W,东-南:E2S * 北-南:N2S, 北-东:N2E,西-东:W2E,西-北:W2N * 右拐:西-南:W2S,南-东:S2E,东-北:E2N,北-西:N2W */ S2N("N2S", false, "S2W"), S2W("N2E", false, "E2W"), E2W("W2E", false, "E2S"), E2S("W2N", false, "S2N"), N2S(null, false, null), N2E(null, false, null), W2E(null, false, null), W2N(null, false, null), W2S(null, true, null), S2E(null, true, null), E2N(null, true, null), N2W(null, true, null); /** * 构造方法 * @param opposite 反方向的灯 * @param lighted 是否是亮的 * @param nextLamp 下一个灯 */ private Lamp(String opposite, boolean lighted, String next){ this.lighted = lighted; this.opposite = opposite; this.next = next; } //灯是否亮 private boolean lighted; //反方向的灯 private String opposite; //下一个灯 private String next; /** * 检测灯是否是亮的 * @return */ public boolean isLighted(){ return this.lighted; } /** * 点亮灯 */ public void light(){ System.out.println(this + "变亮了"); //自己亮 lighted = true; //对面的灯也要亮 if(opposite != null) { Lamp.valueOf(opposite).light(); } } /** * 熄灭灯 */ public Lamp black(){ System.out.println(this + "变灭了"); //自己灭 lighted = false; //对面的灯也要灭 if(opposite != null) { Lamp.valueOf(opposite).black(); } Lamp nextLamp = null; //点亮下一个灯,并返回。 if(next != null) { nextLamp = Lamp.valueOf(next); nextLamp.light(); } return nextLamp; } }
灯控系统:
LampController,控制灯的亮,有一个变量,表示当前的灯:Lamp currentLamp。在构造方法。要有一个初始化灯,并且让当前的灯变绿。
每隔十秒,就让当前灯变红,并让下一个灯变绿。并把当前灯指向新的变绿的灯。
在灯内部,变黑方法,同时把下一个变绿的灯返回。
LampController:
/** * 灯控系统 * @author real * */ public class LampController { private Lamp currentLamp; public LampController() { //初始化灯为S2N currentLamp = Lamp.S2N; //定义一个定时器 ScheduledExecutorService timer = Executors.newScheduledThreadPool(1); //启动线程,延迟1S启动任务,每隔十秒执行一次,把当前灯变灭,并把变亮的灯设置为当前的灯。 timer.scheduleAtFixedRate( new Runnable(){ @Override public void run() { currentLamp = currentLamp.black(); } }, 1, 10, TimeUnit.SECONDS); } }
3.系统测试
所有的类编写完毕,编写测试方法来进行测。生成十二条路,这十二条线路必须和路灯中的十二个名字相同。在此利用数组存储对应的十二字符串,然后在for循环中生成十二条路线。启动控制系统,程序即可运行。LampTest:
public class LampTest { public static void main(String[] args) { //把十二条路线的名字作为一个数组 String[] roads ={"S2N", "S2W", "E2W", "E2S", "N2S", "N2E", "W2E", "W2N", "W2S", "S2E", "E2N", "N2W"}; //生成十二条线路。 for(int i = 0; i < roads.length; i++) { new Road(roads[i]); } //启动灯控系统 new LampController(); } }在每一次的通行中,只能有六个方向进行通行(始终有四个左拐):结果如下:
S2N变灭了 N2S变灭了 S2W变亮了 N2E变亮了 W2S::0 通过路口! N2E::0 通过路口! E2N::0 通过路口! S2E::0 通过路口! W2S::1 通过路口! E2N::1 通过路口! N2W::0 通过路口! E2N::2 通过路口! N2W::1 通过路口! S2W::0 通过路口! S2W变灭了 N2E变灭了 E2W变亮了 W2E变亮了
看了张孝祥老师的视频,在逐渐明白面向对象的精髓,设计好一个系统是如此的重要。在此非常感谢张孝祥老师。希望早日进黑马深造,使自己的能力更上一层楼。
相关文章推荐
- 黑马程序员 JAVA学习笔记——交通灯管理系统
- 黑马程序员 java学习笔记——交通灯管理系统
- 黑马程序员—Java基础学习笔记之7K月薪面试题破解_交通灯管理系统
- 黑马程序员——Java学习笔记之⑨——“交通灯管理系统”
- 黑马程序员_Java学习笔记之7K面试题交通等管理系统
- 黑马程序员_java基础笔记(14)...交通灯管理系统_编码思路及代码
- 黑马程序员_java学习日记_交通灯管理系统
- 黑马程序员——交通灯管理系统学习笔记
- 黑马程序员——学习笔记21.7K面试题之交通灯管理系统
- 黑马程序员_Java学习日记27_交通灯管理系统
- 黑马程序员学习笔记九——交通灯管理系统
- 黑马程序员_7k面试题(交通灯管理系统)学习笔记
- 黑马程序员java学习日记十六 7k面试题交通灯管理系统讲解
- 黑马程序员_交通灯管理系统学习笔记
- 黑马程序员_java基础笔记(14)...交通灯管理系统_编码思路及代码
- Java学习笔记(交通灯管理系统学习)
- 黑马程序员——java 7k银行业务管理系统学习笔记
- 黑马程序员_交通灯管理系统学习笔记
- 黑马程序员高级视频学习笔记交通等管理系统
- 黑马程序员----交通灯管理系统学习笔记