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

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

          昨天学习了交通灯系统,今天又从新看了一下。下个小总结吧。刚一看就懵了,发现原来用的知识怎么都没用上?这一个月来的努力白费了吗。里边不仅加了计时器,线程池,等等新的知识,都是以前没见过的,之后又中很大的失落感,只有又硬着头皮重新看,第二次看的当中,发现了很多小知识点,象匿名内部类了,内部变量访问外部局部变量的方法,等等,得到了温故而知新的效果,而且用上了张老师的关于枚举的一些新知识,交通灯的12条路线用枚举真的很简单。就像张老师说的那样,看到新知识不能害怕,不要觉得没学过,只要用过一次就学会了,以后碰到类似的问题就可以举一反三了。
        学到的最重要的就是如何使用面向对象,里边很重要的一句就是谁拥有数据,谁就对外提供了针对这个数据进行操作的方法。或者这句话现在还不是很了解。但是随着我学习的深入,会慢慢的去了解的。
       像这个例子中,第一步就是画图,弄懂路和灯之间的逻辑。画图也非常有助于理解和分析问题,然后分析这个题目中有几个对象?首先,车是怎么运行的?他是要受到路和灯的控制,车该往哪里走?谁最清楚?灯和路最清楚,灯给车提供了信号,我让你走你才能走,你的听我的,我说的算。路会告诉车下一步 你直走还是转弯等等。所以在这里灯和路都是对象,在考虑灯,他会自己变红变绿吗?不会,谁在控制?lampControllor 他告诉我什么时候亮什么时候红。所以整个项目中的3个对象就明确了。这就是面向对象的思想吧。
      可能我的基础还比较薄弱,对这个项目理解的也不好,现在的了解也只是皮毛。其中的精髓还没有领悟到,等以后基础好点,我会再回来看这道非常经典的项目,不然也对不起张老师。。。
       下边是我根据张老师的视频,跟着打的代码。注释很多,欢迎拍砖。

class Road{
List<String> vechicles = new ArrayList<String>();

private String name = null;
public Road(String name){
  this.name=name;
  //第一个name是成员变量,第二个name是传进来的name是成员函数的局部变量
  //这里要用一个线程池。1.5以上,线程池是一上来就产生好多个线程,有任务交给他运行的时候,看哪个空闲就交给他们去运行。
  //当前我只需要一个线程 那么在线程池上标1. 线程池是一组线程,可以建立一个线程池,让他交给某个线程去做,
  //我不交给某个线程,我要交给这个线程池。让他去调用某个线程。
  //ExecutorService也是个线程池,等同于pool
  ExecutorService pool = Executors.newSingleThreadExecutor();//执行器,如果一个类用作工具 它里边的方法全是静态方法,这个类的名字往往以类打头。像utils
  pool.execute(new Runnable(){//这相当于new了一个Runnable实现类的对象,接口是不能直接new的,但是加个大括号表示new的是他的实现类
   public void run(){
    for(int i=1; i<1000; i++){
     try {
      Thread.sleep((new Random().nextInt(10)+1)*1000);
     } catch (InterruptedException e) {
      e.printStackTrace();
     }
     vechicles.add(Road.this.name +"_"+i);//加上车的名字和第几辆车。
     //内部类要访问外部类的局部变量,局部变量要加final
     //访问外部类的成员变量本来可以直接用外部类成员变量的名字,但是如果这个变量与自己类中的变量名字打架了就必须不能省略Road.this.
    }   
   }
  });

  //定义一个定时器
  ScheduledExecutorService timer =  Executors.newScheduledThreadPool(1);
  timer.scheduleAtFixedRate(
    new Runnable(){
     public void run(){
      if(vechicles.size()>0){
       boolean lighted = Lamp.valueOf(Road.this.name).isLighted();
       //这个路线的名字得到对应的灯,我这条路线由南到北 当然就得到由南到北的灯了 枚举很爽吧
       if(lighted==true){
        System.out.println(vechicles.remove(0)+"is traversing!");
        //这里返回的是 被移走的那个东西。
       }
      } 
     }
    },
    1,//过多少秒之后去干这个事
    1, //干完之后在过多少秒接着干?
    TimeUnit.SECONDS);//这个是前面数字的计数单位
  /*timer.schedule(
    new Runnable(){},
    delay,//delay就是过多长时间干conmand这件事
    unit);*/
}
}
enum Lamp {
S2N("N2S","S2W",false),S2W("N2E","E2W",false),E2W("W2E","E2S",false),E2S("W2N","S2N",false),//只要控制住这四条线路就ok
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.opposite = 传过来的opposite
  this.next = next;
}
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(); //这里是获得字符串opposite的对象.变绿  
  }//我有对应的灯的时候我才让对应的灯亮 比如我东亮了,东对应的西就亮了,
  //这时西就没对应的灯了,不然就死循环了
  System.out.println(name()+"Lamp is Green,下边应该有六个方向能看到汽车通过");
}

public Lamp blackOut(){//灯变红
  this.lighted = false;
  if(opposite != null){
   Lamp.valueOf(opposite).blackOut();  
  }
  Lamp nextLamp = Lamp.valueOf(next);
  if(next != null){
   System.out.println("绿灯从"+"-------》切换为"+next);
   nextLamp.light();
  }
  return nextLamp;
}
}


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();//当前的灯变黑,我的当前灯应该指向新变绿的灯。
     }
    },
    2,
    2,
    TimeUnit.SECONDS);
}
}
class MainClass {

/**
  * @param args
  */
public static void main(String[] args) {
  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();
}
}

---------------------- android培训 java培训 、期待与您交流! ----------------------
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值