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


----------------------- android培训 java培训 、java学习型技术博客、期待与您交流!----------------------

我的初期代码

啥也不说了,线上代码.很经典的题目...
我觉得在定义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.定义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);
	}
}

实现效果:




----------------------- android培训 java培训 、java学习型技术博客、期待与您交流!----------------------

详情请查看:http://edu.csdn.net/

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值