介紹:
用Java編寫對的模擬電梯上下樓。
運(yùn)行截圖:
-
初始化界面

-
電梯進(jìn)行上樓,輸入3 5 -1
-
電梯下樓,輸入2 4 -1
-
出現(xiàn)有電梯上下樓時(shí),根據(jù)上一次電梯運(yùn)行的方向繼續(xù)運(yùn)行。輸入1 3 -1
源代碼,僅供參考。
package cn.szw;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Random;
import java.util.Scanner;
public class elevator {
final static int CAPACITY=1000;
final static int TOP_FLOOR = 12; //電梯最高層
final static int BOTTOM_FLOOR = 1; //電梯最底層
public static void main(String args[]) throws InterruptedException{
System.out.println("該電梯總樓數(shù)是12層,第一層編號為第1層。");
//默認(rèn)當(dāng)前樓層為第一層,z代表當(dāng)前樓層
int z = 1;
//before代表上一次電梯是向上還是向下。1向上,0向下。
int before = 1;
while(true){
//獲得輸入的層數(shù)保存在list中
ArrayList<Integer> list = arrive_List(z);
ArrayList<Integer> list_up = new ArrayList<Integer>();
ArrayList<Integer> list_down = new ArrayList<Integer>();
if((list.size() == 1 && list.get(0) == -1) || list.size()==0) {
System.err.println("電梯不運(yùn)行,在第"+z+"層。");
}else {
//進(jìn)行排序
Collections.sort(list);
if(list.get(0)!=-1){
System.err.println("請按規(guī)則重新輸入樓層,注意結(jié)束后輸入-1!");
continue;
}else{
list.remove(0);
}
System.out.println("正在檢查是否超重。。。");
Thread.sleep(800);
//對體重的大小進(jìn)行判斷
Random_body_weight();
//將上下樓進(jìn)行分成兩個(gè)list
for(int i=0;i<list.size();i++) {
if(list.get(i)>z) {
list_up.add(list.get(i));
}else {
list_down.add(list.get(i));
}
}
//對上樓還是下樓進(jìn)行判斷
}
if(before == 1) {
z = up_up(z, list_up);
z = down_down(z,list_down);
before = change_before(list_down,list_up);
}else{
z = down_down(z,list_down);
z = up_up(z, list_up);
before = change_before(list_down,list_up);
}
}
}
private static int change_before(ArrayList<Integer> list_down, ArrayList<Integer> list_up) {
//返回更新before的值
if(list_down.size()==0) {
return 1;
}else if (list_up.size()==0){
return 0;
}else {
return 0;
}
}
private static int down_down(int z, ArrayList<Integer> list_down) throws InterruptedException {
//遍歷循環(huán)下樓的層數(shù)
for(int q = list_down.size()-1; q >= 0; q--) {
Function_b(list_down.get(q),z);
z = list_down.get(q);
}
return z;
}
private static int up_up(int z,ArrayList<Integer> list_up) throws InterruptedException {
//遍歷循環(huán)上樓的層數(shù)
for(int q = 0; q < list_up.size(); q++) {
Function_a(list_up.get(q),z);
z = list_up.get(q);
}
return z;
}
//對輸入的樓層進(jìn)行存儲
public static ArrayList<Integer> arrive_List(int z) throws InterruptedException{
System.out.println("請輸入您需要去的樓層,結(jié)束后輸入-1。");
ArrayList<Integer> list = new ArrayList<Integer>();
Scanner in = new Scanner(System.in);
//讀入一行數(shù)據(jù)
String str=in.nextLine();
//split函數(shù)是用于按指定字符(串)或正則去分割某個(gè)字符串,結(jié)果以字符串?dāng)?shù)組形式返回
String[] str1=str.split("\\s+");
for(String a : str1){
//將字符串?dāng)?shù)組的元素轉(zhuǎn)換為整型
int number = Integer.parseInt(a);
//二個(gè)條件語句去除非法數(shù)字
if(number==z) {
System.out.println("您就在第"+z+"樓層!");
continue;
}else if(number==-1){
list.add(number);
break;
}else if(number>TOP_FLOOR || number< -1 || number == 0) {
Thread.sleep(800);
System.out.println("您輸入第"+number+"樓,不合法,已去除。");
continue;
}else {
list.add(number);
}
}
//進(jìn)行去除重復(fù)數(shù)字操作
HashSet<Integer> set = new HashSet<Integer>(list);
if(set.size() == list.size()){
return list;
}else{
ArrayList<Integer> list_no_repeat = new ArrayList<Integer>(set);
System.err.println("您輸入的數(shù)字中含有重復(fù)數(shù)字!");
System.out.println(list_no_repeat);
return list_no_repeat;
}
}
//打印上樓
public static void Function_a(int b,int z) throws InterruptedException {
for(int now = z;now <= b;now++) {
Thread.sleep(1000);
System.out.println("...第"+now+"層...");
}
Thread.sleep(1000);
System.out.println("到達(dá)第"+b+"層,開門!");
Thread.sleep(1000);
Random_body_weight();
}
//打印下樓
public static void Function_b(int b,int z) throws InterruptedException {
for(int now = z;now >= b;now--) {
Thread.sleep(1000);
System.out.println("...第"+now+"層...");
}
Thread.sleep(1000);
System.out.println("到達(dá)第"+b+"層,開門!");
Thread.sleep(1000);
Random_body_weight();
}
//電梯體重隨機(jī)生成
public static void Random_body_weight(){
//設(shè)置最大最小的隨機(jī)數(shù)
int max=1300;
int min=40;
Random random = new Random();
//生成隨機(jī)數(shù)s
int s = random.nextInt(max)%(max-min+1) + min;
if(s>CAPACITY){
System.err.println("重量為"+s+"Kg電梯超重,無法關(guān)門。。。");
}else{
System.out.println("重量為"+s+"Kg未超重,正常運(yùn)行。。。");
}
}
}
部分實(shí)現(xiàn)方法思想:
輸入、保存數(shù)據(jù):首先是對數(shù)據(jù)的輸入,用戶在控制臺上輸入想要去的樓層的數(shù)字,最后輸入-1結(jié)束,使用nextLine()將一行的數(shù)據(jù)保存在字符串中,然后再利用split方法將字符串通過分割轉(zhuǎn)換成字符數(shù)組,注意這里的split方法中填入的輸分割字符的字符,我這里使用了正則表達(dá)式,代表去除多個(gè)或一個(gè)空格。存儲到字符串?dāng)?shù)組后,將字符串?dāng)?shù)組進(jìn)行遍歷,將數(shù)據(jù)轉(zhuǎn)化成int類型,然后利用三個(gè)判斷確定是不是非法數(shù)字,如果是的話結(jié)束循環(huán),不將數(shù)據(jù)保存到ArrayList中。保存到ArrayList之后,為了確保不能有重復(fù)數(shù)字,通過Hashset進(jìn)行查重、去重。返回滿意的list。
排序、分組。得到list后將list通過Collections.sort()方法進(jìn)行排序,為了方便上下樓的語句輸出,將list中的數(shù)據(jù)分成兩組,z代表當(dāng)前樓層,初始化值為1,list中的數(shù)據(jù)與z當(dāng)前樓層作比較,如果大的代表需要上的樓層,放入單獨(dú)的一個(gè)list中,比z小的也單獨(dú)放入一個(gè)list集合中。
判斷先下樓還是先上樓:全局定義一個(gè)before變量,初始化值為1。當(dāng)before等于1的時(shí)候,代表上一次電梯運(yùn)行的方向是向上,那么當(dāng)輸入的樓層有向上和向下的時(shí)候時(shí),先會向上運(yùn)行再向下運(yùn)行,運(yùn)行完這次電梯之后,將會更改before的值,將before改為0,下次再遇見上樓和下樓的問題時(shí),就會先下后上。
對輸入重復(fù)的數(shù)字進(jìn)行去重:由于ArrayList自身沒有去重方法,所以這里運(yùn)用了HashSet的特性,HashSet的集合中不能有重復(fù)數(shù)字。創(chuàng)建HashSet,數(shù)據(jù)仍是list中的數(shù)據(jù),之后再判斷兩個(gè)集合的長度是否相等,如果相等代表沒有重復(fù)元素,如果不相等代表含有重復(fù)數(shù)據(jù),返回更改后沒有重復(fù)的數(shù)據(jù)。
體重隨機(jī)數(shù):利用random類中的nextInt方法,數(shù)值在40-1300之間,生成隨機(jī)數(shù)后進(jìn)行判斷是否超過規(guī)定體重,然后返回相應(yīng)的輸出語句。在電梯運(yùn)行的時(shí)候進(jìn)行調(diào)用。
延遲輸出第n層。比如上樓,用for循環(huán)進(jìn)行遍歷集合中的數(shù)據(jù),然后在遍歷中調(diào)用另外一個(gè)方法Function_a(),該方法可以延遲輸出第n層,在這個(gè)方法中給定兩個(gè)參數(shù),到達(dá)的樓層和目前所在的樓層z,然后用for循環(huán)進(jìn)行輸出,Thread.sleep()方法是可以延遲時(shí)間。下樓也是類似的方法。
部分bug:
輸入數(shù)字以外報(bào)異常
結(jié)束需輸入-1,實(shí)際上不輸入-1仍可以結(jié)束