黑马程序员—java之交通灯管理系统理解

黑马程序员—java之交通灯管理系统

 

                                               ------- android培训java培训、期待与您交流! ----------

 

人生最大的悲哀不是失去太多,而是计较太多,这也是导致一个人不快乐的重要原因

 

交通灯管理系统

/*

      需求

这个为张老师模拟的十字路口的交通灯(没有黄灯,且右转的车辆无右转交通灯)

 

具体思维:

1)异步随机生成按照各个路线行驶的车辆。

    例如:由南向而来去往北向的车辆...直行车辆。

                由西向而来去往南向的车辆...右转车辆。

                由东向而来去往南向的车辆...左转车辆。

                ........

2)信号灯0\4 2 3

忽略黄灯,只考虑红灯和绿灯。

3)应考虑左转车辆控制信号灯,右转车辆不受信号灯控制

4)具体信号灯控制逻辑与现实生活中普通交通灯控制逻辑相同,不考虑特殊情况下的控制逻辑。

南北向车辆与东西向车辆交替放行,同方向等待车辆应先放行直行车辆而后放行左转车辆。

5)每辆车通过路口时间为1s。

6)随机生成车辆时时间间隔自定,可以设置。

7)不要求实现GUI,只考虑系统逻辑实现,可通过log方式展现程序运行结果。

 

系统的没戏与设计

系统中有12条路线,每一条上都会出现多辆车,共有12条路线,需要创建12个对象,没条路上随机产生车辆,把这些车厢保存到一个 集合中。

然后没经过一段时间判断路灯的情况若为绿灯这让车辆通过,也就从路的集合中移出一辆车,表示车辆的通过。

红绿灯

系统中有12条路线,可以模拟出12个路灯,Lamp对象需要改变路灯的状态的方法即红绿灯之间的转换。

代码的实现

 

public class MainClass {

 /**

  交通灯信号管理系统

  *@param args

  */

 publicstatic void main(String[] args) {

 

 /**/ 

 String [] directions = new String[]{

   "南向北","南向东","南向西","东向西","东向南","东向北","北向南","北向东","北向西","西向东","西向南","西向北" 

  };

 for(int i=0;i<directions.length;i++){

   newRoad(directions[i]);

 }    

  newLampController();

 }

}

 

创建路对象

 

import java.util.ArrayList;

import java.util.List;

import java.util.Random;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

importjava.util.concurrent.ScheduledExecutorService;

import java.util.concurrent.TimeUnit;

/**

 *  每个Road对象都有一个name成员变量来代表方向,有一个vehicles成员变量来代表方向上的车辆集合。

 *在Road对象的构造方法中启动一个线程每隔一个随机的时间向vehicles集合中增加一辆车(用一个“路线名_id”形式的字符串进行表示)。

 * 在Road对象的构造方法中启动一个定时器,每隔一秒检查该方向上的灯是否为绿,是则打印车辆集合和将集合中的第一辆车移除掉。

 *

 */

public class Road {   //交通工具,代表方向上的车辆集合。

 private List<String> vechicles = newArrayList<String>();//创建集合储存车辆

 

 private String name =null;//代表方向

 publicRoad(String name){

 this.name = name;

 

  //车开到路上的实例对象

 ExecutorService pool = Executors.newSingleThreadExecutor();//创建一个使用单个 worker 线程的 Executor,以无界队列方式来运行该线程。

 pool.execute(new Runnable(){

  public void run(){

   for(int i=1;i<1000;i++){//假设总共有1000辆车

    try {

     Thread.sleep((new Random().nextInt(10) + 1) * 1000);//模拟每一秒到十秒增加一个车(用线程休眠方法)

     }catch (InterruptedException e) {

     e.printStackTrace();

     }

    vechicles.add(Road.this.name + "_" + i);//向vehicles集合中增加一辆车

   }   

   }

  

  });

 

  //

 ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);//创建一个定时器,规定一定时间后执行一个任务

 timer.scheduleAtFixedRate(//scheduleAtFixedRate(Runnable command,  long initialDelay,long period, TimeUnit unit)

    newRunnable(){

    public void run(){//要执行的任务

     if(vechicles.size()>0){

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

      if(lighted){

       System.out.println(vechicles.remove(0) + " 通过路口");

      }

      }

     

    }//在Road对象的构造方法中启动一个定时器,每隔一秒检查该方向上的灯是否为绿,是则打印车辆集合和将集合中的第一辆车移除掉。

     

    },

   1,//首次执行的延迟时间

   1,//连续执行之间的周期

   TimeUnit.SECONDS);

     //来说明签名的数字是代表什么单位(秒 是天))

 }

}

/**

 

                创建交通灯对象

           

1、 系统中有12个方向上的灯,在程序的其他地方要根据灯的名称就可以获得对应的灯的实例对象,

 综合这些因素,将Lamp类用java5中的枚举形式定义更为简单。

2、 每个Lamp对象中的亮黑状态用lighted变量表示,选用南向北、南向西、东向西、东向北这四

 个方向上的Lamp对象依次轮询变亮,Lamp对象中还要有一个oppositeLampName变

 量来表示它们相反方向的灯,再用一个nextLampName变量来表示此灯变亮后的下一个变

 亮的灯。这三个变量用构造方法的形式进行赋值,因为枚举元素必须在定义之后引用,所以无

 法再构造方法中彼此相互引用,所以,相反方向和下一个方向的灯用字符串形式表示。

3、 增加让Lamp变亮和变黑的方法:light和blackOut,对于南向北、南向西、东向西、东向北这

 四个方向上的Lamp对象,这两个方法内部要让相反方向的灯随之变亮和变黑,blackOut方法还要

 让下一个灯变亮。

4、 除了南向北、南向西、东向西、东向北这四个方向上的Lamp对象之外,其他方向上的Lamp对象的

 nextLampName和oppositeLampName属性设置为null即可,并且南向北、南向西、东向西、东向北

 这四个方向上的Lamp对象的nextLampName和oppositeLampName属性必须设置为null,以便防止light和blackOut进

 *

 */

/**/

public enum Lamp {

 /*每个枚举元素个表示灯控制的一个方向*/

 南向北("北向南","南向西",false),南向西("北向东","东向西",false),

 东向西("西向东","东向南",false),东向南("西向北","南向北",false),

 /*下面元素表示与上面的元素的相反方向的等,其中所有的参数值不重要应忽略不计!*/

 北向南(null,null,false),北向东(null,null,false),

 西向东(null,null,false),西向北(null,null,false),

 

 /*有南向东和有西向北不受红绿灯的控制,所以可以假想他们总是绿灯*/

 北向西(null,null,true),西向南(null,null,true),

 南向东(null,null,true),东向北(null,null,true);

 

 

 private Lamp(String opposite,Stringnext,boolean lighted){

 this.opposite = opposite;

 this.next = next;

 this.lighted = lighted;

 }

 

 /*灯是否为绿*/

 private boolean lighted; 

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

 private String opposite;

 /*灯变红时下一个变绿的等*/

 private String next;

 publicboolean isLighted(){

 return lighted;

 }

 

 /**

  * 灯变绿时,它对应方向的灯也要变绿

  */

 publicvoid light(){

 this.lighted = true;

 if(opposite != null){

  Lamp.valueOf(opposite).light();

  }

 

 System.out.println(name() + "灯亮绿色下面总共应该有六个方向能看到汽车穿过");

 

 }

 

 /**

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

  *@return 下一个要变绿的灯

  */

 publicLamp blackOut(){

 this.lighted = false;

 if(opposite != null){

  Lamp.valueOf(opposite).blackOut();

 } 

 

  LampnextLamp= null;

 if(next != null){

  nextLamp = Lamp.valueOf(next);

  System.out.println("绿灯从" + name() + "-------->切换为" + next);  

  nextLamp.light();

  }

 return nextLamp;

 }

}

import java.util.concurrent.Executors;

importjava.util.concurrent.ScheduledExecutorService;

import java.util.concurrent.TimeUnit;

public class LampController {

 private Lamp currentLamp;

 

 publicLampController(){

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

 currentLamp = Lamp.南向北;

 currentLamp.light();

 

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

 ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);

 timer.scheduleAtFixedRate(

    newRunnable(){

     public void run(){

     System.out.println("开始切换转向灯");

     currentLamp = currentLamp.blackOut();

    }

    },

   10,10,TimeUnit.SECONDS);

 }

                                               ------- android培训java培训、期待与您交流! ----------


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值