我的初期代码
啥也不说了,线上代码.很经典的题目...
我觉得在定义Road中存储汽车的集合,应该用LinkedList,因为有addFist和removeLast方法,既符合实际情况,有相对于没有查询,只增删操作,也提高了效率.
还有在定义枚举红绿灯时,也有点小想法,但是还不成熟,先按照老师的整体思路,一步步按照自己的想法做了一遍.
/*
需求:
模拟十字路口交通灯管理系统
分析:
代码体现现实生活,则需要分析哪些对象,分析用什么类型数据进行代码化.
这里这样分析:
名词提炼:有路,有车,有灯
再提炼动作:车来,车过红绿灯,灯变化.
所以总结:
用集合抽象道路,枚举抽象红绿灯,一个操作类抽象灯控制器,一个描述类抽象汽车.
步骤:
1.定义路类集合.用来存储要过红绿灯的汽车.<四>
2.定义灯枚举类,每个实例对象存在四大方向,每个方向有左转,右转,直行3个子属性,并且关联有对应转换方法.<十二>
3.定义汽车描述类,具有来需要行进方向属,性即:要左行,要右行,要中行.<一>
4.定义交通灯的控制类.初始化交通灯.
5.定义测试类.
*/
//定义汽车类.
public class Car{
//定义行进方向数组.
static String[] towardsArr = {"左转","直行","右转"};
privateString towards;
public getTowards(){
return towards;
}
//定义无参构造,车产生则明确行进方向.
public Car(){
this.towards = towardsArr[new Random().next(3)];
}
}
//定义道路类.
public class Rode{
private List<Car> cars = new LinkedList<Car>();
private String name;
public Road(String name){
this.name = name;
//1到5秒随机产生一辆需要过红绿灯的车.
ExecutorService pool = Executors.newSingleThreadExecutor();
pool.execute(new Runnable(){
public void run(){
while(true){
try {
Thread.sleep((new Random().nextInt(10)+1)*1000);
}catch (InterruptedException e) {
e.printStackTrace();
}
//出现一辆需要过红绿灯的车
Car temp = new Car();
cars.addLast(temp);
}
}
});
//定义一个定时器,每个1秒检查红绿灯状态,匹配该路上第一辆车行进方向为绿灯,则该车通行.
ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
timer.scheduleAtFixedRate(new Runnable(){
public void run(){
//判断该路上是否有车,没有车则无需通行.
if(cars.size()>0){
//判断该车所要去方向是否为绿灯,是则通行.
boolean lighted = Lamp.valueOf(Road.this.name+temp.getTowards).isLighted();
if(lighted){
System.out.println("来自"+Road.this.name+temp.towards+"车辆行驶通过..oO");
}
}
}
},1,1,TimeUnit.SECONDS);
}
}
//定义红路灯的枚举
public enum Lamp{
//四个红绿灯.分别以来自某条路和行进方向来命名.
东右转(null,null,true),东左转("西左转","南直行",false),东直行("西直行","东左转",false),
西右转(null,null,true),西左转(null,null,false),西直行(null,null,false),
南右转(null,null,true),南左转("北左转","东直行",false),南直行("北直行","南左转",false),
北右转(null,null,true),北左转(null,null,false),北直行(null,null,false);
//成员属性:是否绿灯(默认为关闭)
private boolean lighted;
//定义获取等状态的方法方法
public boolean isLighted(){
return lighted;
}
//每个灯对应有相对的灯,和左转灯的指向.(这里因为是枚举,就用那个灯名的字符串代替了)
private String opposite;
private String next;
//用构造定义逆向方向看到的灯和左转方向看到的灯的关联关系.
//这里要明确,红绿灯方式为:直行,左转,再逆向直行,逆向左转.右转忽略.
private Lamp(String opposite, String next, boolean lighted){
this.opposite = opposite;
this.next = next;
this.lighted = lighted;
}
//当直行方向绿灯亮起的时候,逆向的绿灯也亮起
public void light(){
this.lighted = true;
//判断该灯是否为直行灯(即他有没有逆向灯.)有则同变绿.
if(opposite != null){
Lamp.valueOf(opposite).lights();
}
}
//当一个灯变红时,他对面的灯变红,同时他的
public Lamp turnOff(){
this.lighted = false;
if(opposite != null){
Lamp.valueOf(opposite).turnOff();
}
//一个方向的直行左转结束后,就要到逆向的
Lamp Lamp = null;
if (next != null) {
nextLamp = Lamp.valueOf(next);
nextLamp.light();
}
return nextLamp;
}
}
//定义红绿灯控制器
public class LampCotroller {
//控制器的作用就是,初始化时一个灯变绿,在一段时间后,变红,调用Lamp的turnOff方法
private Lamp currentLamp;
public LampCotroller() {
currentLamp=Lamp.南直行;
currentLamp.light();
//初始化一个红路灯的开始状态.
ScheduledExecutorService timer=Executors.newScheduledThreadPool(1);
timer.scheduleAtFixedRate(new Runnable(){
public void run(){
currentLamp=currentLamp.turnOff();
}
}, 10, 10, TimeUnit.SECONDS);
}
}
//定义测试类
public class Test{
public static void main(String[] args){
String[] from = {"东","西","南","北"};
for(String temp : from){
new Roda(temp);
}
new LampCotroller();
}
}
分析总结:
分析:
首先需求是要模拟十字路口交通灯管理系统.
所以对对象,对象的方法等进行分析:
名词提炼:有路,有车,有灯
再提炼动作:车来,车过红绿灯,灯变化.
所以抽象出的结论是:
用集合抽象道路,枚举抽象红绿灯,一个操作类抽象灯控制器,一个描述类抽象汽车.
下面是大体的实现步骤:
1.定义路类集合.用来存储要过红绿灯的汽车.<四>
2.定义灯枚举类,每个实例对象存在四大方向,每个方向有左转,右转,直行3个子属性,并且关联有对应转换方法.<十二>
3.定义汽车描述类,具有来需要行进方向属,性即:要左行,要右行,要中行.<一>
4.定义交通灯的控制类.初始化交通灯.
5.定义测试类.
所以对对象,对象的方法等进行分析:
名词提炼:有路,有车,有灯
再提炼动作:车来,车过红绿灯,灯变化.
所以抽象出的结论是:
用集合抽象道路,枚举抽象红绿灯,一个操作类抽象灯控制器,一个描述类抽象汽车.
下面是大体的实现步骤:
1.定义路类集合.用来存储要过红绿灯的汽车.<四>
2.定义灯枚举类,每个实例对象存在四大方向,每个方向有左转,右转,直行3个子属性,并且关联有对应转换方法.<十二>
3.定义汽车描述类,具有来需要行进方向属,性即:要左行,要右行,要中行.<一>
4.定义交通灯的控制类.初始化交通灯.
5.定义测试类.
总结:
首先不得不吐槽下,百度一下,关于交通管理系统这个关键词,就没看到其他不同的代码...跟视频里张老师的代码完全一样...严重怀疑多少人真正写过这个代码.虽然说这个代码不难.不过还是有点感叹,都太懒了...
然后就是我再做的过程中遇到的一些问题.
1.定义Road时,用来存储汽车的集合我认为用LinkedList会更好.
因为
我觉得用LinkedList他有独特的addFist和removeLast方法,既符合实际情况,又在没有查询,只增删操作的情况下,提高了效率.
(LinkedList底层为链表,ArrayList底层为数组)
2.我觉得应该抽象出来一个汽车描述类.
这个类一旦实例化,就应该存在一个属性,就是行进的方向.
然后用出现在那条路上,拼接上车的行进方向确定所需要匹配的红绿灯.
3.还有一个想法,暂时有些迷糊,记录下,稍后再探究.
就是我认为灯的枚举中,应该只有四个灯,而这四个灯中,应该分别有三个属性,就是左转,右转,直行,当然,如何体现,容我下回分解...
Ps.今天是个特殊的日子,二十多年的辛苦打怪补兵,今天终于在老姐的助攻下,成功升级,辈分+1.以后也是有外甥的人了.
当然,更让我难以释怀的是,瞬间觉得任重道远起来...孩子,你舅舅我会好好混滴...
跟新:
关于上面第三个想法,今天自己做了下,将红绿灯数目定为4个,因为事实上每个路口一个灯,只是这个灯中有左转,右转,直行三个成员属性.
还有事关于灯的控制系统,用亮红灯,亮绿灯来控制.
下面是新写的代码:
//定义测试类
public class Test{
public static void main(String[] args){
System.out.println("\t\t\t \t北\t ");
System.out.println("\t\t\t西\t+\t东");
System.out.println("\t\t\t \t南\t ");
//红绿灯开始工作
new LampCotroller();
//车辆出现
String[] from = {"东","西","南","北"};
for(String temp : from){
new Road(temp);
}
}
}
//定义汽车类.
public class Car{
//定义行进方向数组.
static String[] towardsArr = {"左转","直行","右转"};
private int num;
public String getInfo(){
return towards+num;
}
private String towards;
public String getTowards(){
return towards;
}
//定义构造,车产生则明确行进方向.
public Car(int num){
this.num = num;
this.towards = towardsArr[new Random().nextInt(3)];
}
}
//定义枚举交通灯类
public enum Lamp{
东("西","北","南"),
西("东","南","北"),
南("北","东","西"),
北("南","西","东");
//成员属性三个方向的等(true为绿灯,false为红灯):
private boolean 左转 = false;
private boolean 右转 = false;
private boolean 直行 = false;
//定义判断某行进方向是否为绿灯.
public boolean isGreen(String towards) {
switch (towards) {
case "直行":
return 直行;
case "左转":
return 左转;
case "右转":
return 右转;
default:
return false;
}
}
//对面路,交叉路灯指向.
private String opposite;
private String left;
private String right;
//初始化灯枚举实例.
private Lamp(String opposite,String left,String right){
this.右转 = true;
this.opposite = opposite;
this.left = left;
this.right = right;
}
//一个灯先直后左,对面路灯与之相同,垂直路灯与之相反,
//定义变绿方法
public void transformGreen(){
直行 = true;
左转 = false;
//同步其他灯的状态
synch();
System.out.println("--------------------------------------------");
System.out.println(this.name()+opposite+"\t直行方向\t绿灯---左转方向\t红灯");
System.out.println(right+left+"\t直行方向\t红灯---左转方向\t绿灯");
System.out.println("--------------------------------------------");
}
//定义变红方法
public void transformRed(){
直行 = false;
左转 = true;
//同步其他灯的状态.
synch();
System.out.println("--------------------------------------------");
System.out.println(this.name()+opposite+"\t直行方向\t红灯---左转方向\t绿灯");
System.out.println(right+left+"\t直行方向\t绿灯---左转方向\t红灯");
System.out.println("--------------------------------------------");
}
//定义私有方法,封装同步其他灯的装态
private void synch(){
Lamp.valueOf(opposite).直行 = 直行 ;
Lamp.valueOf(opposite).左转 = 左转 ;
Lamp.valueOf(left).直行 = !直行 ;
Lamp.valueOf(left).左转 = !左转 ;
Lamp.valueOf(right).直行 = !直行 ;
Lamp.valueOf(right).左转 = !左转 ;
}
}
//定义红绿灯控制器
public class LampCotroller {
public LampCotroller() {
// 指定一个初始化用红绿灯.
ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
timer.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
if (Lamp.南.isGreen("直行")) {// 开启控制系统.必然有第一个灯是红或者绿的情况.
Lamp.南.transformRed();
} else {
Lamp.南.transformGreen();
}
}
}, 0, 10, TimeUnit.SECONDS);
}
}
//定义道路
public class Road{
private LinkedList<Car> cars = new LinkedList<Car>();
private String name;
public Road(String name){
this.name = name;
//1到5秒随机产生一辆需要过红绿灯的车.
ExecutorService pool = Executors.newSingleThreadExecutor();
pool.execute(new Runnable(){
public void run(){
int count = 1;
while(true){
try {
Thread.sleep((new Random().nextInt(10)+1)*1000);
}catch (InterruptedException e) {
e.printStackTrace();
}
//出现一辆需要过红绿灯的车
cars.addLast(new Car(count++));
}
}
});
//定义一个定时器,每个1秒检查红绿灯状态,匹配该路上第一辆车行进方向为绿灯,则该车通行.
ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
timer.scheduleAtFixedRate(new Runnable(){
public void run(){
//当且仅当该路上有车时判断是否过红绿灯.
if(cars.size()>0){
//判断该车要去方向是否为绿灯.是则同行.
if( Lamp.valueOf(Road.this.name).isGreen(cars.getFirst().getTowards())){
System.out.println("来自\t"+Road.this.name+"边\t"+cars.removeFirst().getInfo()+"号车辆\t行驶通过");
}
}
}
},
1,
1,
TimeUnit.SECONDS);
}
}
实现效果: