读书人

黑马软件工程师_java学习日记_面试题_

发布时间: 2013-03-26 09:54:34 作者: rapoo

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

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

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

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

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

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

面向对象:

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

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

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

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

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

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

关于灯的设计

无论何时都是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();

??? }

?

}

读书人网 >编程

热点推荐