第一次Blog作业(电梯)
一、前言
自刚开始学习JAVA以来已经有一个多月了,也是迎来了人生第一个JAVA小项目——电梯运行模拟。这第一个项目难度评估不是很高,但是里面有许多的坑等着我们去钻,尽管平时的训练我都做的得心应手,但是这个项目对于第一次做项目的我而言还是稍稍偏难。
二、设计与分析
题目概述:
设计一个电梯类,具体包含电梯的最大楼层数、最小楼层数(默认为1层)当前楼层、运行方向、运行状态,以及电梯内部乘客的请求队列和电梯外部楼层乘客的请求队列,其中,电梯外部请求队列需要区分上行和下行。
电梯运行规则如下:电梯默认停留在1层,状态为静止,当有乘客对电梯发起请求时(各楼层电梯外部乘客按下上行或者下行按钮或者电梯内部乘客按下想要到达的楼层数字按钮),电梯开始移动,当电梯向某个方向移动时,优先处理同方向的请求,当同方向的请求均被处理完毕然后再处理相反方向的请求。电梯运行过程中的状态包括停止、移动中、开门、关门等状态。当电梯停止时,如果有新的请求,就根据请求的方向或位置决定移动方向。电梯在运行到某一楼层时,检查当前是否有请求(访问电梯内请求队列和电梯外请求队列),然后据此决定移动方向。每次移动一个楼层,检查是否有需要停靠的请求,如果有,则开门,处理该楼层的请求,然后关门继续移动。
使用键盘模拟输入乘客的请求,此时要注意处理无效请求情况,例如无效楼层请求,比如超过大楼的最高或最低楼层。还需要考虑电梯的空闲状态,当没有请求时,电梯停留在当前楼层。
请编写一个Java程序,设计一个电梯类,包含状态管理、请求队列管理以及调度算法,并使用一些测试用例,模拟不同的请求顺序,观察电梯的行为是否符合预期,比如是否优先处理同方向的请求,是否在移动过程中处理顺路的请求等。为了降低编程难度,不考虑同时有多个乘客请求同时发生的情况,即采用串行处理乘客的请求方式(电梯只按照规则响应请求队列中当前的乘客请求,响应结束后再响应下一个请求),具体运行规则详见输入输出样例。
输入格式:
第一行输入最小电梯楼层数。
第二行输入最大电梯楼层数。
从第三行开始每行输入代表一个乘客请求。
电梯内乘客请求格式:<楼层数>
电梯外乘客请求格式:<乘客所在楼层数,乘梯方向>,其中,乘梯方向用UP代表上行,用DOWN代表下行(UP、DOWN必须大写)。
当输入“end”时代表输入结束(end不区分大小写)。
输出格式:
模拟电梯的运行过程,输出方式如下:
运行到某一楼层(不需要停留开门),输出一行文本:
Current Floor: 楼层数 Direction: 方向
运行到某一楼层(需要停留开门)输出两行文本:
Open Door # Floor 楼层数
Close Door
输入样例:
在这里给出一组输入。例如:
1
20
❤️,UP>
<5>
<6,DOWN>
<7>
<3>
end
输出样例:
在这里给出相应的输出。例如:
Current Floor: 1 Direction: UP
Current Floor: 2 Direction: UP
Current Floor: 3 Direction: UP
Open Door # Floor 3
Close Door
Current Floor: 4 Direction: UP
Current Floor: 5 Direction: UP
Open Door # Floor 5
Close Door
Current Floor: 6 Direction: UP
Current Floor: 7 Direction: UP
Open Door # Floor 7
Close Door
Current Floor: 6 Direction: DOWN
Open Door # Floor 6
Close Door
Current Floor: 5 Direction: DOWN
Current Floor: 4 Direction: DOWN
Current Floor: 3 Direction: DOWN
Open Door # Floor 3
Close Door
附录:
电梯运行过程详解(LOOK算法)
输入:
1
20
❤️,UP>
<5>
<6,DOWN>
<7>
<3>
end
楼层最小值:1
楼层最大值:20
电梯外:3楼向上请求
电梯内:去5楼
电梯外:6楼向下请求
电梯内:去7楼
电梯内:去3楼
输入结束标志
输出:
Current Floor: 1 Direction: UP
Current Floor: 2 Direction: UP
Current Floor: 3 Direction: UP
Open Door # Floor 3
Close Door
Current Floor: 4 Direction: UP
Current Floor: 5 Direction: UP
Open Door # Floor 5
Close Door
Current Floor: 6 Direction: UP
Current Floor: 7 Direction: UP
Open Door # Floor 7
Close Door
Current Floor: 6 Direction: DOWN
Open Door # Floor 6
Close Door
Current Floor: 5 Direction: DOWN
Current Floor: 4 Direction: DOWN
Current Floor: 3 Direction: DOWN
Open Door # Floor 3
Close Door
当前楼层:1,方向:向上
当前楼层:2,方向:向上
当前楼层:3,方向:向上
当前楼层:3,开门
关门
当前楼层:4,方向:向上
当前楼层:5,方向:向上
当前楼层:5,开门
关门
当前楼层:6,方向:向上
当前楼层:7,方向:向上
当前楼层:7,开门
关门
当前楼层:6,方向:向下
当前楼层:6,开门
关门
当前楼层:5,方向:向下
当前楼层:4,方向:向下
当前楼层:3,方向:向下
当前楼当前楼层:3,开门
关门
按照题目说明,乘客请求为一次性输入,乘客请求分为电梯内和电梯外两个队列,分别为:
电梯内:
InnerQueue <5> <7> <3>
电梯外:
OuterQueue ❤️,UP> <6,DOWN>
电梯运行过程如下:
1.电梯默认值停留在1层,状态为Stopped(停止),方向为IDLE(无方向)
2.程序开始运行,检测IQ(InnerQueue)和OQ(OutQueue)两个队列排在最前面的请求,
如果任意不为空,则代表有乘客请求,应该运行,检测结果为队列不为空,开始运行
3. 首先判断运行方向,离电梯当前层(1层)最近的为OQ内的第一个元素的请求楼层3,3>1,
则向上然后电梯开始向上运行,状态为Moving(移动),方向为UP(向上),输出:“当
前楼层:1,方向:向上”,
4. 运行到第2层,判断该楼层是否应该停下来处理请求,判断后应继续移动(请求是3),
输出“当前楼层:2,方向:向上”
5. 运行到第3层,判断该楼层是否应该停下来处理请求,判断后应停止处理请求(请求是
3,当前楼层是3),状态变为Stopped,输出“Open Door # Floor 3回车Close Door”,此
时将IQ和OQ两个队列中的队头的3层请求全部出队(删除)
6. 关门后电梯状态为“Stopped”,继续检测两个队列的队头请求,分别是<5>和<6,DOWN>,
取同向且离得近的请求,即<5>,得出电梯运行方向应维持UP
7. 继续向上运行,运行到第4层,判断该楼层是否应该停下来处理请求,判断后应继续移
动(请求是5),输出“当前楼层:4,方向:向上”
8. 继续向上运行,运行到第5层,判断该楼层是否应该停下来处理请求,判断后应处理请
求(请求是5,且方向为UP,与电梯同向),状态变为Stopped,输出“Open Door # Floor
5 回车Close Door”,此时将IQ和OQ两个队列中的队头的5层请求全部出队(删除)
9. 关门后电梯状态为“Stopped”,继续检测两个队列的队头请求,分别是<7>和<6,DOWN>,
取同向且离得近的请求,即<7>,得出电梯运行方向应维持UP
10. 继续向上运行,运行到第6层,判断该楼层是否应该停下来处理请求,判断后应继续移
动(请求是7),输出“当前楼层:6,方向:向上”
11. 继续向上运行,运行到第7层,判断该楼层是否应该停下来处理请求,判断后应处理请
求(请求是7,且方向为UP,与电梯同向),状态变为Stopped,输出“Open Door # Floor
7 回车Close Door”,此时将IQ和OQ两个队列中的队头的7层请求全部出队(删除)
12. 关门后电梯状态为“Stopped”,继续检测两个队列的队头请求,分别是<3>和<6,DOWN>,
取同向且离得近的请求,结果为空,此时可判定当前电梯向上方向的请求已经全部处理完毕,
此时方向应转向,即从UP到DOWN,此时取同向离得最近的请求,即<6,DOWN>,得出电
梯运行方向应向下
13. 继续向下运行,运行到第6层,判断该楼层是否应该停下来处理请求,判断后应处理请
求(请求是6,且方向为DOWN,与电梯同向),状态变为Stopped,输出“OpenDoor#Floor
6 回车Close Door”,此时将IQ和OQ两个队列中的队头的6层请求全部出队(删除)
14. 关门后电梯状态为“Stopped”,继续检测两个队列的队头请求,只剩下是<3>,取同向
且离得近的请求,即<3>,得出电梯运行方向应维持DOWN
15. 运行到第5层,判断该楼层是否应该停下来处理请求,判断后应继续移动(请求是3),
输出“当前楼层:5,方向:向下”
16. 运行到第4层,判断该楼层是否应该停下来处理请求,判断后应继续移动(请求是3),
输出“当前楼层:5,方向:向下”
17. 运行到第3层,判断该楼层是否应该停下来处理请求,判断后应处理请求(请求是3),
状态变为Stopped,输出“Open Door # Floor 3回车Close Door”,此时将IQ和OQ两个队
列中的队头的3层请求全部出队(删除)
18. 关门后电梯状态为“Stopped”,继续检测两个队列的队头请求,结果为空,此时电梯运
行结束,状态为“Stopped”,方向变为“IDEL”,电梯停留在3层
分析设计:
在一开始,我并没有理清楚类与类之间的关系和代码的整体运行逻辑,非常盲目的去编写代码,后面立刻遇到了问题:类与类相互的调用无法进行、代码进度无法推进。苦思冥想后仍无结果,最后在与同学交流、听取老师意见后收货颇丰,也是寻得了解决办法,进行新一次的代码优化与迭代。再后面遇到了数组、队列使用相关的问题,也踩了不少坑,后来在不断阅读相关资料和与同学讨论后得以解决。在编写代码期间,也遇到了许多读写和分析的麻烦,为了应对输入输出的百般变化,也是绞尽脑汁,虽虽然最后并没有写出来,也是开拓了新的眼界和思路。
三、踩坑心得和教训:
这一次小项目的作业踩了不少坑,每一次看着写好的代码报错,每一次删掉历经千辛万苦得出的结果,都让我痛苦万分。我发现最痛苦的事不是写多少多少代码,而是写错了,得改,得删。这样的后果起源于对题目不认真审、对结构不认真设计、对内容不认真思考。如果能够克服这三个问题,认真对待每一个环节,那么代码删改的痛苦会少很多甚至没有。在编写代码过程中,难免会碰到一些问题,有时苦思冥想也不能得出结果,在这一次作业中,我通过与同学交流、听取老师意见解决了问题,这让我明白啥:技术是在不断交流、不断碰撞中得以进步的,因此我们不能闭门造车而是要去讨论、去吸取。我相信这些心得与体会能让我在JAVA的学习之路上行的更远。
四、总结
在这一次电梯运行模拟项目的学习之中,我收获了许多知识与经验,这些提升了我对代码的使用水平,加深了我对程序设计的理解。这个项目的内容十分贴近我们的生活,这也是我们专业的特点——来源于生活,服务于需求。

浙公网安备 33010602011771号