需求:
模擬實現十字路口的交通燈管理系統邏輯,具體需求如下:
異步隨機生成按照各個路線行駛的車輛。
例如:
由南向而來去往北向的車輛 ---- 直行車輛
由西向而來去往南向的車輛 ---- 右轉車輛
由東向而來去往南向的車輛 ---- 左轉車輛
。。。
信號燈忽略黃燈,只考慮紅燈和綠燈。
應考慮左轉車輛控制信號燈,右轉車輛不受信號燈控制。
具體信號燈控制邏輯與現實生活中普通交通燈控制邏輯相同,不考慮特殊情況下的控制邏輯。
注:南北向車輛與東西向車輛交替放行,同方向等待車輛應先放行直行車輛而後放行左轉車輛。
每輛車通過路口時間爲1秒(提示:可通過線程Sleep的方式模擬)。
隨機生成車輛時間間隔以及紅綠燈交換時間間隔自定,可以設置。
不要求實現GUI,只考慮系統邏輯實現,可通過Log方式展現程序運行結果。
分析:
首先是他給的方向自己一會就暈了。
所以先按照一個方向 南 來分析
如圖所示 從南向北
從南向西
從南向東(右行可以忽略)
面向對象分析和設計
抽象出四類對象
問題1 .車在路上走 車不斷減少 車不斷減少的方法是 是車提供還是路提供 ????一點 誰對外提供數據,誰就提供對外訪問的方法。 車在路上 ,即路對外提供數據 所以
路提供對外訪問的方法。
紅綠燈 :1.總共12個燈 任何時候都不用new燈 所以用枚舉來解決
2. 三種 狀態 :自己的狀態 ,下一個燈,相反的燈。 即三個成員變量
紅綠燈的控制器:當前燈是哪一個,有個定時器 ,時間已到就把當前的燈變紅。 變紅的方法得返回下一個燈
路:每創建一個對象就指定他的名字,每一秒種路上就來一輛車
代碼:
package cn.itheima.interview.traffic;
public class MainClass {
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();
}
}
package cn.itheima.interview.traffic;
public enum Lamp {
S2N("N2S","S2W",false),S2W("N2E","E2W",false),E2W("W2E","E2S",false),E2S("W2E","E2S",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 nextLamp,boolean lighted ){
this.opposite=opposite;
this.next=nextLamp;
this.lighted=lighted;
}
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把枚舉類型給它 他就給返回一對應枚舉類型的對象
//opposite.light();
}
System.out.println(name() + " lamp is green,下面總共應該有6個方向能看到汽車穿過!");
}
public Lamp 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;
}
}
package cn.itheima.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> vehicles= new ArrayList<String>();//交通工具 因爲路上行駛不僅是小汽車
private String name=null;//路的名字
public Road(String name){//final 加final也能解決問題
this.name=name;
//產生100輛車 產生車也就是向路里面添加車那條路上的車
//Executors.newFixedThreadPool(1);或者
ExecutorService pool= Executors.newSingleThreadScheduledExecutor();
pool.execute(new Runnable(){
@Override
public void run() {
for(int i=0;i<100;i++){
//讓車有時候多有時少
try {
Thread.sleep((new Random().nextInt(10)+1)*1000);//1-10s的休息時間
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
vehicles.add(Road.this.name+"_"+i);//某方向的某輛車
}
}});
//定時器的製作
ScheduledExecutorService timer=Executors.newScheduledThreadPool(1);
timer.scheduleAtFixedRate(
new Runnable() {
@Override
public void run() {
// 移走第一輛車
//在有車的情況下才移走一次
if(vehicles.size()>0){
//假如燈是綠的才移動車boolean lighted = Lamp.valueOf(Road.this.name).isLighted();
boolean lighted=Lamp.valueOf(Road.this.name).isLighted();
if(true){
System.out.println(vehicles.remove(0)+"is traversing");;
}
}
}
},
1,
1,
TimeUnit.SECONDS);
}
}
package cn.itheima.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() {
@Override
public void run() {
currentLamp=currentLamp.blackOut();
//currentLamp.
}
},
10,
10,
TimeUnit.SECONDS);
}
}
汽車看到自己所在路線對應的燈綠了就穿過路口嗎?不是,還需要看其前面是否有車,看前面是否有車,該問哪個對象呢?該問路,路中存儲着車輛的集合
根據張老師講的幾點 對我有用的幾點幫助的總結
個是大師們說的寫的代碼 起得名字非常得當 讓人看起了就懂 to=2 for=4
總結 自己犯的錯誤
1.內部類訪問 外部類的是name屬性 忘了this.name =name;
理解是外部類的屬性 而不是構造方法裏 傳過來的name 形參
2.當張老師把
Lamp nextLamp=null;
if(next!=null){
nextLamp=Lamp.valueOf(next);
System.out.println("綠燈從" + name() + "-------->切換爲" + next);
nextLamp.light();
} 這段代碼寫錯的時候自己已經意識到了 因爲自己也犯過類似的錯誤