黑馬程式設計師之----------7K面試題之交通燈管理
------<a href="http://www.itheima.com" target="blank">Java培訓、Android培訓、iOS培訓、.Net培訓</a>、期待與您交流! -------
Java 交通燈管理系統
交通燈管理系統
一.需求:
模擬實現十字路口的交通燈管理系統邏輯,
二.畫圖非常有助於理解和分析問題。圖如下:
三.面向物件的分析與設計
交通燈管理系統所涉及的物件:包括交通燈,路線 ,控制燈變化的物件,汽車,以及主方法。
汽車看到自己所在路線對應的燈綠了就穿過路口嗎?
不是,還需要看其前面是否有車,看前面是否有車,該問哪個物件呢?
該問路,路中儲存著車輛的集合,
顯然路上就應該有增加車輛和減少車輛的方法了。
再看題目,我們這裡並不要體現車輛移動的過程,只是捕捉出車輛穿過路口的過程,
也就是捕捉路上減少一輛車的過程,所以,這個車並不需要單獨設計成為一個物件,用一個字串表示就可以了。
1、每條路線上都會出現多輛車,路線上要隨機增加新的車,在燈綠期間還要每秒鐘減少一輛車。
(1)、設計一個Road類來表示路線,每個Road物件代表一條路線,總共有12條路線,即系統中總共要產生12個Road例項物件。
(2)、每條路線上隨機增加新的車輛,增加到一個集合中儲存。
(3)、每條路線每隔一秒都會檢查控制本路線的燈是否為綠,是則將本路線儲存車的集合中的第一輛車移除,即表示車穿過了路口。
2、每條路線每隔一秒都會檢查控制本路線的燈是否為綠,一個燈由綠變紅時,應該將下一個方向的燈變綠。
(1)、設計一個Lamp類來表示一個交通燈,每個交通燈都維護一個狀態:亮(綠)或不亮(紅),每個交通燈要有變亮和變黑的方法,
並且能返回自己的亮黑狀態。
(2)、總共有12條路線,所以,系統中總共要產生12個交通燈。右拐彎的路線本來不受燈的控制,
但是為了讓程式採用統一的處理方式,故假設出有四個右拐彎的燈,只是這些燈為常亮狀態,即永遠不變黑。
(3)、除了右拐彎方向的其他8條路線的燈,它們是兩兩成對的,可以歸為4組,所以,在程式設計處理時,
只要從這4組中各取出一個燈,對這4個燈依次輪詢變亮,與這4個燈方向對應的燈則隨之一同變化,
因此Lamp類中要有一個變數來記住自己相反方向的燈,在一個Lamp物件的變亮和變黑方法中,將對應方向的燈也變亮和變黑。
每個燈變黑時,都伴隨者下一個燈的變亮,Lamp類中還用一個變數來記住自己的下一個燈。
(5)、設計一個LampController類,它定時讓當前的綠燈變紅。
面向物件設計把握一個重要的經驗:誰擁有資料,誰就對外提供操作這些資料的方法
四.Road類的編寫
1、每個Road物件都有一個name成員變數來代表方向,有一個vehicles成員變數來代表方向上的車輛集合。
2、在Road物件的構造方法中啟動一個執行緒每隔一個隨機的時間向vehicles集合中增加一輛車(用一個“路線名_id”形式的字串進行表示)。
3、在Road物件的構造方法中啟動一個定時器,每隔一秒檢查該方向上的燈是否為綠,是則列印車輛集合和將集合中的第一輛車移除掉。
4、在講Road物件的定時器程式碼時,因為開始階段還沒有設計Lamp類,所以,檢查該方向上的燈是否為綠的程式碼暫時先採用短路方式。
五.Lamp類的編寫
1、系統中有12個方向上的燈,在程式的其他地方要根據燈的名稱就可以獲得對應的燈的例項物件,綜合這些因素,
將Lamp類用java5中的列舉形式定義更為簡單。
2、每個Lamp物件中的亮黑狀態用lighted變量表示,選用S2N、S2W、E2W、E2N這四個方向上的Lamp物件依次輪詢變亮,
Lamp物件中還要有一個oppositeLampName變數來表示它們相反方向的燈,再用一個nextLampName變數來表示此燈變亮後的下一個變亮的燈。
這三個變數用構造方法的形式進行賦值,因為列舉元素必須在定義之後引用,所以無法再構造方法中彼此相互引用,
所以,相反方向和下一個方向的燈用字串形式表示。
3、增加讓Lamp變亮和變黑的方法:light和blackOut,對於S2N、S2W、E2W、E2N這四個方向上的Lamp物件,
這兩個方法內部要讓相反方向的燈隨之變亮和變黑,blackOut方法還要讓下一個燈變亮。
4、除了S2N、S2W、E2W、E2N這四個方向上的Lamp物件之外,其他方向上的Lamp物件的nextLampName和oppositeLampName屬性設定為null即可,
並且S2N、S2W、E2W、E2N這四個方向上的Lamp物件的nextLampName和oppositeLampName屬性必須設定為null,
以便防止light和blackOut進入死迴圈。
六.LampController類的編寫
1、整個系統中只能有一套交通燈控制系統,所以,LampController類最好是設計成單例。
2、LampController構造方法中要設定第一個為綠的燈。
3、LampController物件的start方法中將當前燈變綠,然後啟動一個定時器,每隔10秒將當前燈變紅和將下一個燈變綠。
七.MainClass類的編寫
1、用for迴圈創建出代表12條路線的物件。
2、接著再獲得LampController物件並呼叫其start方法。
3、String [] directions = {"S2N","N2S","S2W","N2E","E2W","W2E",
"E2S","W2N","S2W","N2W","E2N","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; /** * 用集合表示路,12條路,就是12Road物件,系統開始要有12個物件, 路上隨機增加車, * 就是在集合增加一個物件保持, * 每條路線每隔一秒都會檢查控制本路線的燈是否為綠,就是把沒條路第一個物件去除所以集合是有順序的 */ public class Road { private List<String> vechicles = new ArrayList<String>(); // 集合,有順序儲存車元素 private String name = null; // 定義路上對應的燈 public Road(String name) { // 因為路已初始化就會有車輛,所以程式碼應該封裝在路的建構函式中 this.name = name; // 路創建出物件時候就開始 模擬車輛不斷隨機上路的過程 /* * ExecutorService執行緒池,Executors 類為這些 Executor 提供了便捷的工廠方法。 * newSingleThreadExecutor()建立一個使用單個 worker 執行緒的 Executor 以無界佇列方式來執行該執行緒。 */ ExecutorService pool = Executors.newSingleThreadExecutor(); /* * void execute(Runnable command)在未來某個時間執行給定的命令。 * 該命令可能在新的執行緒、已入池的執行緒或者正呼叫的執行緒中執行, 這由 Executor 實現決定 */ pool.execute(new Runnable() { public void run() { for (int i = 1; i < 1000; i++) { try { // 產生1到10秒隨機數 Thread.sleep((new Random().nextInt(10) + 1) * 1000); } catch (InterruptedException e) { e.printStackTrace(); } // 集合裡面增加一個車,名字是路名+順序數字 vechicles.add(Road.this.name + "_" + i); } } }); // 每隔一秒檢查對應的燈是否為綠,是則放行一輛車建立一個定時器的執行緒池 /* * public interface ScheduledExecutorServiceextends ExecutorService 一個 * ExecutorService,可安排在給定的延遲後執行或定期執行的命令。 */ ScheduledExecutorService timer = Executors.newScheduledThreadPool(1); /* * scheduleAtFixedRate(Runnable command, long initialDelay, long period, * TimeUnit unit) 建立並執行一個在給定初始延遲後首次啟用的定期操作, 後續操作具有給定的週期; * 也就是將在 initialDelay後開始執行,然後在 initialDelay+period 後執行, * 接著在 initialDelay + 2 * period後執行,依此類推。 */ timer.scheduleAtFixedRate(new Runnable() { public void run() { // 如果路上有車,就每隔1秒判斷一次燈,若燈為綠,那麼就將第一輛車取走 if (vechicles.size() > 0) { boolean lighted = Lamp.valueOf(Road.this.name).isLighted(); if (lighted) { System.out.println(vechicles.remove(0) + " is traversing !"); } } } }, 1, 1, TimeUnit.SECONDS);// TimeUnit.SECONDS列舉 } } /** * 列舉中每個Lamp元素代表一個方向上的燈,總共有12個方向,所以有12個元素 * 例如正南、正北2燈是一組,一起紅或者綠,所以只要控制正南燈保持正北燈就可以了,這樣一共有4組, * 由於從南向東和從西向北、以及它們的對應方向不受紅綠燈的控制,可以假想它們總是綠燈。 */ public enum Lamp { /* * 12個列舉元素各表示一個方向的控制燈,4組燈中只要控制每一組的一個燈變化就可以,另個保持一致 */ 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 Lamp(String opposite, String next, boolean lighted) { // 構造方法,3個引數,同組對應的燈,下個燈,紅綠情況 this.opposite = opposite; this.next = next; this.lighted = lighted; } // 構造方法傳遞的引數,true綠燈 private boolean lighted; // 定義燈的相反方向的燈 private String opposite; // 當前燈變紅時下一個變綠的燈(相鄰的燈) private String next; /** * 構造方法傳遞的引數的方法,true綠燈 */ public boolean isLighted() { return lighted; } /** * 燈變綠的方法 某個燈變綠時,它同組對應方向的燈也要變綠 */ public void light() { this.lighted = true;// 燈變綠 if (opposite != null) {// 它同組對應方向的燈存在情況執行 // valueOf方法,根據值來反向獲取Lamp物件:</span></strong></span></span> // Lamp lamp = Lamp.valueOf(opposite); Lamp.valueOf(opposite).light(); } // 重要:name()返回此列舉常量的名稱,在其列舉宣告中對其進行宣告。 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; } } import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; /** * 燈控制器,每隔10秒將當前綠燈變為紅燈,並讓下一個方向的燈變綠 */ //控制燈的亮 public class LampController { // 定義當前的燈 private Lamp currentLamp; public LampController() { //設定剛開始讓由南向北的燈變綠; currentLamp = Lamp.S2N; currentLamp.light(); // 定時器每隔10秒將當前綠燈變為紅燈,並讓下一個方向的燈變綠 ScheduledExecutorService timer = Executors.newScheduledThreadPool(1); timer.scheduleAtFixedRate(new Runnable() { public void run() { currentLamp.blackOut(); } }, 10, 10, TimeUnit.SECONDS); } } /* 執行類,在開始執行後 * 產生12個方向的路線,併產生整個交通燈系統讓其開始工作 * / 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(); } }
------<a href="http://www.itheima.com" target="blank">Java培訓、Android培訓、iOS培訓、.Net培訓</a>、期待與您交流!
-------
相關推薦
【黑馬程式設計師】7k面試題之交通燈
交通燈專案需求: 模擬實現十字路口的交通燈管理系統邏輯,具體需求如下: 非同步隨機生成按照各個路線行駛的車輛。 例如: 由南向而來去往北向的車輛 ---- 直行車輛 由西向而來去往南向的車輛 ---- 右轉車輛
【黑馬程式設計師】7K面試題之銀行排程系統
模擬實現銀行業務排程系統邏輯,具體需求如下: Ø 銀行內有6個業務視窗,1- 4號視窗為普通視窗,5號視窗為快速視窗,6號視窗為VIP視窗。 Ø 有三種對應型別的客戶:VIP客戶,普通客戶,快速客戶(辦理如交水電費、電話費之類業務的客戶)。
黑馬程式設計師11-7k面試題交通燈
---------------------- android培訓、java培訓、期待與您交流! ---------------------- 1,交通燈管理系統的需求是什麼? 非同步隨機產生按照各個路線行駛的車輛 比如: 由南向北行駛的車輛視為直行車輛 由南向西行駛的車輛視為左行車輛 。。。 訊號燈忽略黃
黑馬程式設計師之----------7K面試題之交通燈管理
------<a href="http://www.itheima.com" target="blank">Java培訓、Android培訓、iOS培訓、.Net培訓</a>、期待與您交流! -------
黑馬程式設計師--Java基礎面試題整理
------- <a href="http://www.itheima.com" target="blank">android培訓</a>、<a href="http://www.itheima.com" target="blank">j
黑馬程式設計師_7k面試題(交通燈管理系統)學習筆記
總共有12條路線,為了統一程式設計模型,可以假設每條路線都有一個紅綠燈對其進行控制,右轉彎的4條路線的控制燈可以假設稱為常綠狀態,另外,其他的8條線路是兩兩成對的,可以歸為4組,所以,程式只需考慮圖中標註了數字號的4條路線的控制燈的切換順序,這4條路線相反方向的路線的控制燈跟隨這4條路線切換,不必額外考慮
黑馬程式設計師-java就業面試題大全(持續更新)
13、是否可以從一個static 方法的內部發出對於非static方法的呼叫? 不可以,因為非static方法要和物件相關聯,必須建立物件後,才可以在該物件上進行方法的呼叫,而static方法呼叫時不需要建立物件。也就是說,當一個static方法被呼叫時可能還沒用建立任何例項物件,那麼要掉用非static方
黑馬程式設計師_7K面試題_交通燈管理系統
-面向物件分析設計經驗:誰用於資料,誰就對外提供操作這些資料的方法。 典型案例: 人在黑板上畫圓。 分析: 共有三個物件:人、黑板、圓。動作:畫 畫圓需要圓心和半徑,圓心和半徑都是圓的屬性上,圓擁有資料,所以圓物件提供畫圓的方法 圓在黑板上,黑板擁有
黑馬程式設計師_面試題1(交通燈管理系統)
一.專案需求: 模擬實現十字路口的交通燈管理系統邏輯: 非同步隨機生成按照各個路線行駛的車輛。 例如: 由南向而來去往北向的車輛 ---- 直行車輛 由西向而來去往南向的車輛 ---- 右
黑馬程式設計師--第二十七天:交通燈系統
---------------------- ASP.Net+Android+IO開發S、.Net培訓、期待與您交流! ---------------------- //總體上減少了Lamp列舉的2個成員變數和2個方法以及test類的一個數組。 //LampContro
黑馬程式設計師----7k面試題之交通燈管理系統
畫圖非常有助於分析和理解問題。 十字路總共有12條線路,為了統一程式設計模型,可以假設每條線路都有一個紅綠燈對其進行控制, 右拐的四條線路假設稱為常綠狀態,另外,其他的8條兩兩成對的,可以歸為4組, 所以程式只需考慮途中標註了數字號的4條線路的控制燈的切換順序, 這四條路線的反方向的路線控制燈跟隨
黑馬程式設計師-7k面試題之交通燈管理系統
---------------------- ASP.Net+Unity開發、.Net培訓、期待與您交流! ---------------------- 面試題要求: 1.非同步隨機生成按照各種路線行駛的車輛。例如:由南向而來去往北向的車輛--------直行車輛由西向
黑馬程式設計師-----7K面試題之交通燈系統
------<a href="http://www.itheima.com" target="blank">Java培訓、Android培訓、iOS培訓、.Net培訓</a>、期待與您交流! ------- 現在每晚都加大力度去學習和加強自己的J
黑馬程式設計師_Java學習筆記之7K面試題交通等管理系統
------- <a href="http://www.itheima.com" target="blank">android培訓</a>、<a href="http://www.itheima.com" target="blank">
黑馬程式設計師 【】java學習之路——列舉小結
------- android培訓、java培訓、期待與您交流! ---------- (注:小弟剛自學一小段時間,這是我學習中的認識,簡單總結下,大神們不要拍我哈 , 說的不對之處還請指出來,多多
黑馬程式設計師 【】java學習之路——代理小結
-------android培訓、java培訓、期待與您交流! ---------- 第一次看代理說實話是一點也沒看懂,聽的雲裡霧裡的,沒辦法接著看第二遍吧,第二遍看完終於
黑馬程式設計師 【】java學習之路——小小的學習心得
------- android培訓、java培訓、期待與您交流! ---------- 又是一個夜深人靜的晚上!這種生活已經有點習慣了!因為我已經破釜沉舟
黑馬程式設計師 【】java學習之路——網路程式設計 UDP 鍵盤錄入傳輸
import java.net.*; import java.io.*; class UdpRece2 {public static void main(String[] args) throws Exception{DatagramSocket ds = new DatagramSocket(10001)
黑馬程式設計師 【】java學習之路——GUI開始簡析三
------- android培訓、java培訓、期待與您交流! ---------- 需求:實現如下視窗,功能:能夠轉到相應的碟符下顯示該盤內的內容 <span style="font-size:18px;">import java.awt.*; impor
黑馬程式設計師 【】java學習之路——TCP客戶端和服務端的建立
------- android培訓、java培訓、期待與您交流! ---------- 演示TCP傳輸 1:tcp分客戶端和服務端 2:客戶端對應的物件是Socket 服務端對應的是S