黑马程序--java面试题之交通灯

 -------------------------------------------android培训期待与您交流 -------------------------------------  

 

模拟实现十字路口的交通灯系统逻辑,具体需求如下:

异步随机生成按照各个路线形式的车辆.

              由南向而来去往北向的车辆---直行车辆

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

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

              .....

信号灯忽略黄灯,值考虑红灯和绿灯.

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

具体信号灯控制逻辑与现实生活中普通交通灯扩至逻辑相同,不考虑特殊状况

       下的控制逻辑.

       注:南北向车辆与东西向车辆交替放行,同方向等待车辆应先放行直线车辆而

       后放行左转车辆.

每辆车通过路口时间为1秒(提示:可通过线程sleep的方式模拟)

随机生成车辆时间间隔以及红绿灯交换时间间隔自定,可以设置.

不要求实现GUI,值考虑系统逻辑实现,可通过log方式

 

展现程序运行结果.

线路数量分析:

总共有12条线路,为了统一编程模型,可以假设每条路线上都有一个红绿灯对其进行控制,右转弯的4条线路的控制等可以假设为常绿状态,另外其它的8条线路是两两成对的,可以归为4组,所以,程序只需要考虑途中标注了数字号的控制等切换顺序,这4条路线相反的路线的控制等跟随者4条线路切换,不必考虑其它.,

线路对应分析(相对方向亮)

黑马程序--java面试题之交通灯

 

 

面向对象的分析与设计:

(!!!!!补充:面向对象设计把握一个重要的经验:谁拥有数据,谁就对外提供操作这些数据的方法)

 

详细设计:(工程名traffic)

一.1Lamp枚举类,灯

1.1 每个枚举元素各表示一个方向的控制灯

S2N("N2S","S2W",false),
S2W("N2E","E2W",false),
E2W("W2E","E2S",false),
E2S("W2N","S2N",false),

 

1.2 下面元素表示与上面的元素的相反方向的灯,它们的“相反方向灯”和“下一个灯”应忽略不计!

N2S(null,null,false),
N2E(null,null,false),
W2E(null,null,false),
W2N(null,null,false),

 

1.3 由南向东和由西向北等右拐弯的灯不受红绿灯的控制,所以,可以假想它们总是绿灯

S2E(null,null,true),
E2N(null,null,true),
N2W(null,null,true),
W2S(null,null,true);

 

 

2控制系统LampController

2.1获取当前等的变量

2.2获取一定时器,时间到,当前等转为红灯,并且下一个方向的等转为绿灯

 

3.路Road

 

二.部分所需类以及方法整理:

1

ExecutorService pool = Executors.newScheduledThreadPool(1);

 

创建一个线程池,-------------线程池(线程数)

2

Road.this.name

 

//第一种解决方案:内部类访问外部类成员变量,在外部类名前加final

//返回外部类的成员变量,为了避免与自己内部类的名字打架,所以:Road.this.name

3

new Random().nextInt(10)

 

//返回0~9的随机数

4

ScheduledFuture<?>   schedule(Runnable command, long delay, TimeUnit unit)

 

//创建并执行在给定延迟后启用的一次性操作。

//(线程,推迟时间,推迟时间单位)

5

ScheduledFuture<?>  scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)

 

//创建并执行开始时间,然后过了多少秒之后继续干,再过多少秒再干, 再过多少秒再干, 再过多少秒再干......

//(线程,过多少秒之后去做,然后过多少秒再去干,时间单位)

6

TimeUnit.SECENDS

 

//时间单位.事件类型

7

valueOf(Class<T> enumType, String name)

 

返回带指定名称的指定枚举类型的枚举常量。

 

代码实现:

----------------Road.class----------------------
package cn.itcast.interview.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 {
   //车的集合
   private List<String> vechicles = new ArrayList<String>();//为了面向接口编程,所以是List集合
  
   private String name=null;
   //每条路线的名字
   public Road(String name)//内部类访问外部类,想访问外部类的局部变量,外部类必须加final(final String name)
   {
      this.name = name;
      //新建一个线程,用于添加汽车
      //newScheduledThreadPool线程池(线程数)
       ExecutorService  pool= Executors.newScheduledThreadPool(1);
     
       //创建一个线程,定隔多少秒进行休息
       pool.execute(new Runnable()//执行池执行,new 了一个Runnable()实现对象
      {
         public void run()
         {
            for(int i =1;i<1000;i++)//产生999辆车
            {
                try {
                   Thread.sleep((new Random().nextInt(10)+1)*1000);//返回0~9的随机数,再加一,就可以是1~10秒
                } catch (InterruptedException e) {
                   e.printStackTrace();
                }
                vechicles.add(Road.this.name+"_"+i);//返回外部类的成员变量,为了避免与自己内部类的名字打架,所以:Road.this.name
            }
         }
      });
       
       //定时器
       ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
       
       //循环定时器
       timer.scheduleAtFixedRate(new Runnable(){
             public void run()
             {//首先检查是否有车
                 if(vechicles.size()>0)
                 {
                    /*定义变量,之后就是在这里修改的..修改去检查这个灯
                    boolean lighted = true;
                    检查自己的灯,name为自己路线的名字,然后Lamp.valueOf(Road.this.name)获取自己路线的名字,
                    把自己的名字传过去,就获得了自己的灯*/
                    boolean lighted = Lamp.valueOf(Road.this.name).isLighted();
                    
                    if(lighted)
                   //假如灯是绿的
                    System.out.println(vechicles.remove(0)+"is traversing !");
                 }
             }
             },
             1,//开始时间
             1,//循环时间
             TimeUnit.SECONDS);//时间单位
   }
}
 
 
-----------------Lamp.class----------------------
 
package cn.itcast.interview.traffic;
//灯
 
public enum Lamp {
   //首先定义12个方向变量
   //这四个是进行控制的
   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 Lamp()//不带参数的构造方法,为了让空值的家伙们不报错,因为有的没有对应的灯
   {
     
   }
  
  
   //灯是否是亮的变量
   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();//传递对应灯的字符串,然后valueOf(),
         //valueOf()返回带指定名称的指定枚举类型的枚举常量。
      }
     
      //测试用
      System.out.println(name()+"lamp is green.下面共有6个方向的车穿过...");
   }
   //熄灯..变红
   public Lamp blackOut()
   {
      this.lighted = false;
      if(opposite !=null)
      {
         Lamp.valueOf(opposite).blackOut();//传递对应灯的字符串,然后valueOf(),
         //valueOf()返回带指定名称的指定枚举类型的枚举常量。
      }
     
      Lamp nextLamp = null;
     
      //如果有下一个灯,那么让下一个灯变绿,下一个等变绿之后,还会返回下一个变绿的灯
      if(next !=null)
      {
         nextLamp = Lamp.valueOf(next);
        
         //测试用
         System.out.println("绿灯从"+name()+"-------->切换为"+next);
        
         Lamp.valueOf(next).light();
        
      }
      return nextLamp;
   }
}
 
 
-----------LampController.class------------------
package cn.itcast.interview.traffic;
 
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
 
//灯的控制器
public class LampController {
   //当前的灯
   private Lamp currentLamp;
  
   //构造方法
   public LampController()
   {
      //指定第一个灯并且当前的灯为绿的
      currentLamp = Lamp.S2N;
      currentLamp.light();
     
      //定义一个定时器,过一段时间,让灯变色
      ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
      timer.scheduleAtFixedRate(
            new Runnable()
            {
                public void run()
                {
                   currentLamp = currentLamp.blackOut();//当前灯变黑
                }
            },
            10,
            10,
            TimeUnit.SECONDS);
     
   }
}
-----------MainClass.class------------------
package cn.itcast.interview.traffic;
/**
 *
 * @author Chen_zyan
 *
 */
public class MainClass {
   /**
    * @param args
    */
   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();//控制器
       }
}

 

 

你可能感兴趣的:(Java面试题)