黑马程序员java-交通灯管理系统《十》

                   ——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——

1,交通灯管理系统原理与分析

首先明白它的工作原理,由于刚刚学车,大概明白交通灯是如何运作的,一般来说车右转是默认不用看灯的,可以直接右转的,

但有时候当交通有箭头显示的时候又不一样了,所以我们不考虑这种情况。那么默认右转灯是一直绿的。根据东南西北四个方向

的车都有各自的三种路线,按道理,东南西北四个方向都有各自的三个方向的交通灯。从车方面考虑就有12(3x4)种路线,而

对应的交通灯也有12个。现在单从一个方向去讨论,比如说南(South)的方向,有三种情况,向右转(即南到东方向)是不用理的,

所以剩下直行(南到北)和左转(南到西),假设直行的灯变绿了,则对应方向(北到南)也要变绿。直行的灯变红后,则对应方向

(北到南)也要变红,而下一个灯左转(南到西)就要变绿。其他方向也是这么分析。

2,车和灯和灯控制的分析

车:12种路线的车每个一段时间就在该路线添加一辆车,每秒检查当前方向的灯是否变绿,如何变绿则当前方向的车就要删除。

灯:12种方向的灯,南(South)的方向,有三种情况,向右转(即南到东方向)是不用理的,所以剩下直行(南到北)和左转(南到西),

假设直行的灯变绿了,则对应方向(北到南)也要变绿。直行的灯变红后,则对应方向(北到南)也要变红,而下一个灯左转(南到西)就要变绿。所以基本上每种方向的灯要关联两个相关方向的灯。

路:一共有12种路线,每个路线要要与相同方向的车对应。

3,面向对象思想设计交通灯系统

(1)  :很明显这是自定义的一种类,而最好的实现方式就是java的枚举类来实现。

每个Lamp元素代表一个方向上的灯,总共有12个方向,所有总共有12个Lamp元素。

有如下一些方向上的灯,每两个形成一组,一组灯同时变绿或变红,所以,程序代码只需要控制每组灯中的一个灯即可:s2n,n2s  s2w,n2e  e2w,w2e

e2s,w2n   s2e,n2w  e2n,w2s。上面最后两行的灯是虚拟的,由于从南向东和从西向北、以及它们的对应方向不受红绿灯的控制,

所以,可以假想它们总是绿灯。所以一共有12个lamp元素,实际上用到的是4组灯即四个方向的灯。lamp元素的构造方法里应该有上面分析过

的两个相关联方向的灯,还有一个自己灯状态的值(false或者true)。灯应该有判断自己灯状态的方法,还有变绿和变红的方法。

灯的代码如下:

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 Lamp(String opposite,String next,boolean lighted){

this.opposite = opposite;

this.next = next;

this.lighted = lighted;

}

  /*当前灯是否为绿*/

private boolean lighted;

/*与当前灯同时为绿的对应方向*/

private String opposite;

/*当前灯变红时下一个变绿的灯*/

private String next;

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个方向能看到汽车穿过!");

  }

  /**

 * 某个灯变红时,对应方向的灯也要变红,并且下一个方向的灯要变绿

 * @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;

}

} 

(2)   路线:一共有12条路线,即要产生12个实例对象,每条路线上随机增加新的车辆,而车就可以添加到一个集合中保存。

以便处理。每条路线每隔一秒都会检查控制本路线的灯是否为绿,是则将本路线保存车的集合中的第一辆车删除,即表示车穿过了路口。

路的类,路有自己路线的名字,而路线上的车的名字应该相同,都用字符串表示,如“s2n”,车辆不断随机上路的过程最好用线程来实现,

而添加车辆的过程可以用for循环来实现。既然有添加车辆就要删除车辆,因为是通过每秒中检查当前路线的灯是否为绿的,所以也要用线程来实现,

判断当前路线的灯是否为绿,如果为绿,则删除最前面的车辆,即第一部车。

路的代码如下:

public class Road {

private List<String> vechicles = new ArrayList<String>();

   private String name =null;

public Road(String name){

this.name = name;

  //模拟车辆不断随机上路的过程

ExecutorService pool = Executors.newSingleThreadExecutor();

pool.execute(new Runnable(){

public void run(){

for(int i=1;i<1000;i++){

try {

Thread.sleep((new Random().nextInt(10) + 1) * 1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

vechicles.add(Road.this.name + "_" + i);

}

}

 });

 //每隔一秒检查对应的灯是否为绿,是则放行一辆车

ScheduledExecutorService timer =  Executors.newScheduledThreadPool(1);

timer.scheduleAtFixedRate(

new Runnable(){

public void run(){

if(vechicles.size()>0){

boolean lighted = Lamp.valueOf(Road.this.name).isLighted();

if(lighted){

System.out.println(vechicles.remove(0) + " is traversing !");

}
}
}
},
1,
1,
TimeUnit.SECONDS);
 }
}

(3)  灯的控制类:每隔10秒将当前绿灯变为红灯,并让下一个方向的灯变绿。所以也要通过线程来实现。

代码如下:

public class LampController {

private Lamp currentLamp;

public LampController(){

//刚开始让由南向北的灯变绿;

currentLamp = Lamp.S2N;

currentLamp.light();

/*每隔10秒将当前绿灯变为红灯,并让下一个方向的灯变绿*/

ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);

timer.scheduleAtFixedRate(

new Runnable(){

public  void run(){

System.out.println("来啊");

currentLamp = currentLamp.blackOut();

}

},
10,
10,
TimeUnit.SECONDS);

}
}

(4)  启动程序

public class MainClass {

  public static void main(String[] args) {

 /*产生12个方向的路线*/

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();

}
}

总结:

难点:

1.交通系统的业务逻辑不容易了解。

2.处理的各种交通情况比较多,需要用到枚举类细化每个情况

3.如何以面向对象的思想思考:如何设计类,以及类的属性和行为。类与类之间有什么关系和相互影响。

时间: 2024-10-26 05:14:09

黑马程序员java-交通灯管理系统《十》的相关文章

黑马程序员_交通灯管理系统

(1)项目的需求 模拟实现十字路口的交通灯管理系统逻辑,具体需求如下: 例如: 由南向而来去往北向的车辆 右转车辆 由东向而来去往南向的车辆 ---- 左转车辆 平时开车过十字路口红绿灯的时候,也知道红绿灯运行的顺序 (1)任何方向的车,向右边转弯的时候,是不需要看红绿灯 (2)在十字路口,相对方向的红绿灯的工作方式是一样的,南相对与北,东相对与西,这把它分成两对 (3)红绿灯顺序,一对直行通道绿灯直行车辆,等直行变红,还是这对的车辆可以左转,等左转变红,就轮到下一对了.所以在设计程序的时候,只

黑马程序员___交通灯管理系统

----------- android培训.java培训.java学习型技术博客.期待与您交流! --------- 交通灯管理系统的项目需求 异步随机生成按照各个路线行驶的车辆. 例如: 由南向而来去往北向的车辆 ---- 直行车辆 由西向而来去往南向的车辆 ---- 右转车辆 由东向而来去往南向的车辆 ---- 左转车辆 ... 信号灯忽略黄灯,只考虑红灯和绿灯. 应考虑左转车辆控制信号灯,右转车辆不受信号灯控制. 具体信号灯控制逻辑与现实生活中普通交通灯控制逻辑相同,不考虑特殊情况下的控制

黑马程序员--关于交通灯管理系统的分析和思考

------- <a href="http://www.itheima.com" target="blank">android培训</a>.<a href="http://www.itheima.com" target="blank">java培训</a>.期待与您交流! ---------- 1. 交通灯管理系统的项目需求 (1).异步随机生成按照各个路线行驶的车辆 (2).信

黑马程序员-java 7K面试题之交通灯管理系统

------- android培训.java培训.期待与您交流! -------- 交通灯管理系统 模拟实现十字路口的交通灯管理系统逻辑,具体需求如下: 1. 异常随机生成按照各个路线行驶的车辆. 例如: 由南向而来去往北向的车辆----直行车辆 由西向而来去往南向的车辆----右转车辆 由东向而来去往南向的车辆----左转车辆 .......  ...... 2. 信号灯忽略黄灯,只考虑红灯和绿灯. 3. 应该考虑左转车辆控制信号灯,右转车辆不受信号灯控制. 4. 具体信号灯控制逻辑与现实

黑马程序员——Java枚举和自动装箱

------- android培训.java培训.期待与您交流! ----------                                                                            枚举类和自动装箱     一.枚举      枚举由不重复的常量构成,在java中使用enmu关键字定义枚举,所有的枚举会自动继承java.lang.enmu. 比如定义交通灯的枚举. publicenumTrafficLamp { RED ,GREED,YEL

黑马程序员——Java基础---IO(下)

黑马程序员——Java基础---IO(下) ------<a href="http://www.itheima.com" target="blank">Java培训.Android培训.iOS培训..Net培训</a>.期待与您交流! ------ 一.概述 Java除了基本的字节流.字符流之外,还提供了File类.properties类.打印流.序列流等和输入输出相关的类,它们能够帮助我们更好的处理信息.下面将对它们进行简单的介绍. 一.正

黑马程序员——Java高新技术代理

代理 普通代理 很多时候,我们使用别人代码往往会发现别人代码的功能并不是十分符合我们的需求,调用别人的方法的时候,总是先new一个对象,然后我们的前处理做完,然后调用别人代码的方法,再加入后处理,这样做往往十分麻烦.代理就为其他类提供了一种控制其对象的方法.代理类和委托类必须实现同一个接口,这样代理类才能在需要的时候代替委托类对象,执行委托类的方法. interface Solution{ public void doSomething(); } //委托类Demo实现了接口 class Dem

黑马程序员——Java I/O流基础知识点(File类)

File工具 File类就是用俩将文件或者文件夹封装对象,弥补流对象的不足--流只能操作数据,不能操作文件夹的 封装的是路径!!! 构造方法演示 1.可以将已有的未出现的文件或者文件夹封装成对象. File f1=new File("c:\\abc\\a.txt"): File f2=new File("d:\\abc","ab.txt"打印,会打印路径.:目录分隔符,为了更好地跨平台File. File类常见功能 1,创建 createNewF

黑马程序员 ---------- Java网络技术之 ---正则表达式 (Day06)

---------------------- ASP.Net+Unity开发..Net培训.期待与您交流! ---------------------- 正则表达式 正则表达式:基本知识 1  字符,   2 字符类 , 3 预定义字符类 , 4 边界匹配器 ,5 Greedy 数量词,6 Logical 运算符 详解: 1 字符 x   字符 x \\ 反斜线字符 \0n 带有八进制值 0 的字符 n (0 <= n <= 7) \0nn 带有八进制值 0 的字符 nn (0 <= n