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

来源:互联网 发布:网络婚恋女骗男 编辑:程序博客网 时间:2024/05/17 06:13

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

终于进入传说中的7k面试题系列学习了,也正是检测一下自己的实力的时候了,祥叔一共讲了两道题:交通灯管理系统和银行调度系统。

咋一看,好复杂啊,交通灯管理系统要考虑的因素太多了,不过经过祥叔的细细剖析,却也渐显明朗。

首先交通灯出现的四岔路口共有12条供车辆穿行的路线,其中四条右拐弯路线可以设计为灯常绿状态,其他的另外8条路线可以归为四组。

这里祥叔说了一点小插曲,也蛮重要的——面向对象的设计经验,即:谁拥有数据就向外提供操作该数据的方法,并举了几个小例子加以佐证:人在黑板上画圆,列车司机紧急刹车等。

从上面的小插曲我们可以知道,路线是提供存储车辆的方法的集合,要想知道路上有多少辆车,就得问路,还有每条路线上必须随机增加新的车辆,添加到路这个集合中保存。同时每条路线每隔一秒检查本路线的灯是否为绿,是则将本路线保存的集合中的第一辆车移除,即表示车穿过了路线。但是路线共有12条,所以我们要定义一个Road类来表示路线,产生12个路的实例对象来代表每一条路线,它们分别是:"S2N","S2W","E2W","E2S","N2S","N2E","W2E","W2N","S2E","E2N","N2W","W2S"。

示例代码如下:

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 classRoad {

    private List<String> vehicles=newArrayList<String>();

    private String name=null;

    public Road(String name){

        this.name=name;

        ExecutorServicepool=Executors.newSingleThreadExecutor();

        pool.execute(new Runnable(){

            public void run(){

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

                    try {

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

                    }catch(InterruptedException e) {

                       

                        e.printStackTrace();

                    }

                    vehicles.add(Road.this.name+"_"+i);//这里可以把String name定义成final类型的,即Road(final Stringname)

                    //另一种解决方式是同外部类.this.name方式访问外部变量,因为内部类的变量名与外部变量名重复

                }

            }

        });

         ScheduledExecutorService timer=Executors.newScheduledThreadPool(1);

         //定义一个定时器,每隔一秒检查一下路灯是否为绿,若是,则移除一辆

         timer.scheduleAtFixedRate

         (new Runnable(){

             public voidrun(){

                 if(vehicles.size()>0){

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

                 if(lighted){

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

                 }

                 }

             }

         },

                 1,

                 1,

                 TimeUnit.SECONDS);

       

         

    }

   

}

 

系统中有12个方向上的灯,在程序的其他地方要根据灯的名称就可以获得对应的灯的实例对象,综上所述,我们可以采用java5 中的枚举形式比较简单,而且灯具有控制亮(绿)和黑(红)的功能,具体代码如下:

public enumLamp {

 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;

 

 privateLamp(String opposite,String next,boolean lighted){//这里构造方法里面不能直接传入Lamp的变量,因为要被传入的变量尚未被定义,所以这里改为传入String的名字

      this.opposite=opposite;

      this.next=next;

      this.lighted=lighted;

 }

 privateString opposite;

 privateString next;

 public boolean isLighted(){

      return lighted;

 }

 

 public void light(){

      this.lighted=true;//对应成组的灯必须只有一方能有对应的灯,另一方没有,否则就会造成死循环

      if(opposite!=null){

          Lamp.valueOf(opposite).light();//将字符串类型的名字转化成Lamp枚举类型的变量通过valueOf

         

      }

     System.out.println(name()+"lamp  is  green  下面应该有六个方向的车穿过马路!");  

 }

 

 publicLamp 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; 

 }

 

}

  

  当然,这个系统中需要一个灯的控制类,而且整套系统只能有一套控制系统,所以控制灯的类最好设计成单例,而且在构造方法中须设定第一个绿的灯,然后启动一个定时器,每隔10秒将当前灯变红和将下一个灯变绿。代码如下:

import java.util.concurrent.Executors;

import java.util.concurrent.ScheduledExecutorService;

import java.util.concurrent.TimeUnit;

 

public classLampController {

 

    private Lamp currentLamp;

   

    public LampController(){

         currentLamp=Lamp.S2N;

         currentLamp.light();

         

         ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);

         timer.scheduleAtFixedRate(

                 new Runnable(){

                     public voidrun(){

                         currentLamp=currentLamp.blackOut();

                     }

                 },

                 10,

                 10,

                 TimeUnit.SECONDS);

    }

}

程序到这里基本已经写完了,最后剩下的就是MainClass类了,负责调用方法和打印最终的结果,由于总共要创建12个对象,那么为了使代码更为紧凑,采用循环的方式进行新建实例对象,代码如下:

public classMainClass {

 

   

    public static void main(String[] args) {

        String[]directions=newString[]{"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();

       

    }

 

}

至此,交通灯系统代码编写完成,虽然我自己随视频写了一遍,但是还没有完全掌握,我想,这还需我进行多次临摹,才能烂熟于心。

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

原创粉丝点击