`
AlexShaw
  • 浏览: 12904 次
  • 性别: Icon_minigender_1
  • 来自: 青岛
最近访客 更多访客>>
社区版块
存档分类
最新评论

黑马程序员_java学习日记_面试题_交通灯管理系统

 
阅读更多

--------------------- android培训java培训java学习型技术博客、期待与您交流! ----------------------

遇到问题不要偷懒,画图有助于理解问题

车辆的行驶顺序,先是直线,比如南向北,然后是左拐外南向西,其他三个方向类似

除去不受控制的灯,这样只剩下8条需要考虑,而这8条中都是成对出现的,所以只需要考虑四条就可以

右拐弯也有灯。只不过是常绿的

绿灯情况下,先是直行,后是拐弯,然后换灯

面向对象:

首先考虑这个情景有哪些对象

灯,灯的控制系统,汽车,路线

路线和灯绑定。汽车看到自己路上所对应的的灯绿了才会走,还要看前面是否有车,也就是说只有自己是第一个位置才能行走,于是路应该有addremove方法用于增删车辆

路上的车可以看做是一个集合,于是路就应该有增加车辆和减少车辆的方法

面向对象设计的重要经验:谁拥有数据,谁就对外提供操作这些数据的方法,谁就是类

面向对象的分析涉及:人在黑板上画圆   黑板

关于灯的设计

无论何时都是12个灯,因此用到枚举

当一个灯变绿,相反方向的灯也会变绿,当一个灯变红,相反方向的灯也变红,而下一个等要变红或变绿,所以该枚举至少俩参数,对面的灯和下一个灯,还有一个参数是自己的状态,自己是不是绿的

灯变红和变绿方法应该返回下一个灯

首先创建一个类road,不同的路线有不同的名字,因此提供含参构造方法,构造方法里面不能sleep,否则永远不返回

publicclass Road {

   

    //定义一个集合用来存储车辆

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

    //路线的名字

    private String name = null;

    public Road(String name)

    {

       this.name = name;

       //假设每1S路上上来一辆车,其他的不管

       //车应该一辆辆上来,而不是一下子全部上来,因此要用计数器

       //创建一个使用单个 worker 线程的 Executor 线程池

       ExecutorService pool = Executors.newSingleThreadExecutor();

       //如果有一个任务,交给一个线程池,线程池自己挑一个空闲的线程去执行他

       pool.execute(new Runnable()//{}表示new了一个runnable的实现类对象

       {

 

           @Override

           publicvoid run() {

              for(int i = 0 ; i < 100 ; i++)

              {

                  try {

                     //随机1-10秒钟上来一辆车

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

                     //访问外部类成员变量本来可以直接访问,但如果外部类的变量名字和内部类的相同则需要外部类.this.属性名

                  } catch (InterruptedException e) {

                     e.printStackTrace();

                  }

                  list.add(Road.this.name+":"+i);

              }

           }

       });

       //创建一个调度池

       ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);

       //计时器每个多长时间去干这件事。参数为要执行的代码,多少秒之后去做,每隔多少秒去做,计时单位

       //重载形式是多少秒之后去做,只做一次

       //timer.schedule(command, delay, unit)

       timer.scheduleAtFixedRate(new Runnable(){

                 

                            @Override

                            publicvoid run() {

                                //检查有没有车

                                if(list.size() > 0)

                                {

                                   //假如灯是绿的

                                   if(Lamp.valueOf(Road.this.name).isGreen())

                                   {

                                       //remove方法返回值是被移除的元素

                                       System.out.println(list.remove(0)+"is removed!");

                                   }

                                }

                               

                            }},

                            1,

                            1,

                            TimeUnit.SECONDS);

    }

}

创建灯.java

 

 

publicenum Lamp {

 

    //S2N,S2W,E2W,E2S,N2S,N2E,W2E,W2N,S2E,E2N,N2W,W2S

    //不使用N2S而是“N2S”是因为必须先定义后使用

    //第一个是对面的灯,第二个是下一个灯,第三个是灯是否是亮的

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

    //点亮灯

    privatebooleangreen;

    //对应的灯的名字,为了解决先定义后使用的问题直接使用对象无法继续写

    private String opposite;

    //下一个灯

    private String next;

    //枚举的构造方法必须私有

    private Lamp(String opposite,String next,boolean green)

    {

       this.opposite = opposite;

       this.next = next;

       this.green = green;

    }

    private Lamp()

    {

      

    }

   

    //是否是亮的

    publicboolean isGreen()

    {

       returngreen;

    }

    publicvoid becomegreen()

    {

       //opposite.becomegreen(); 我的灯亮了,就让对应的灯也亮,但是不能这样写,会陷入死循环

       this.green = true;

       //假如我为主,我有对应的灯,而对面的灯没有对应的灯

       if(opposite != null)

       {

           Lamp.valueOf(opposite).becomegreen();

       }

       System.out.println(name()+"变绿了");

    }

    public Lamp becomered()

    {

       this.green = false;

       if(opposite != null)

       {

           Lamp.valueOf(opposite).becomered();

       }

       Lamp nextLamp = null;

       if(next != null)

       {

           nextLamp = Lamp.valueOf(next);

           nextLamp.becomegreen();

       }

       System.out.println(name()+"变红了");

       return nextLamp;

    }

}

灯的控制器

publicclass LampControler {

    private Lamp currentLamp;

   

    public LampControler(){

       //加定第一个灯为E2N,然后让他变绿灯

       currentLamp = Lamp.S2N;

       currentLamp.becomegreen();

       ScheduledExecutorService c = Executors.newScheduledThreadPool(1);

       c.scheduleAtFixedRate(new Runnable(){

           @Override

           publicvoid run() {

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

              //因为该方法需要下一个灯作为返回值使灯来回切换所以becomered方法需要返回下一个灯

              currentLamp = currentLamp.becomered();

             

           }

          

       },

       10,

       10,

       TimeUnit.SECONDS);

    }

}主类

 

publicclass Main {

 

    /**

     * @param args

     */

    publicstaticvoid main(String[] args) {

       String[] str = new String[]{"S2N","S2W","E2W","E2S","N2S","N2E","W2E","W2N","S2E","E2N","N2W","W2S"};

       for(String s : str)

       {

           new Road(s);

       }

       new LampControler();

    }

 

}

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics