一.案例說明
本案例並主要是對集合的綜合運用,並且實現集合的CRUD功能。也是對javaEE基礎知識的綜合運用,運用面向對象的思想(面向過程分析,以及封裝、繼承、多態)實現簡單的需求分析。
本案例也存在一些bug,一些細節後續再改進(修改版本1.3)。
二.案例需求分析
根據功能先劃分類別(封裝不同的類來實現不同的需求)。
1.Country類
用於封裝各個國家信息的數據。
2.Check類
這是專門用於對錄入的信息進行校驗。
3.OperationMethod類
操作方法類,所有功能的實現都封裝在這個類中。包括添加奧運獎牌信息、查看奧運獎牌信息、修改奧運獎牌信息、刪除奧運獎牌信息、返回功能、繼續錄入功能等。
4.Menu類
包括主菜單、二級菜單、返回菜單等。
5.StartSMS類
這是主程序,用於測試程序運行的類。
三.代碼實現(所有的類都在一個包下,cn.jason)
1.country類
package cn.jason;
/**
* 這是封裝所有國家信息的類
*
* @blog http://blog.csdn.net/yan_yuhan
* @author Jason
* @version 1.2
* @2016年9月15日 上午0:41:13
*/
public class Country {
// 定義國家名稱
private String countryName;
// 定義金牌數
private String gold;
// 定義銀牌數
private String sliver;
// 定義銅牌數
private String copper;
// 定義獎牌總數,按照獎牌總數排序
private int medalSum;
// 國家類的無參構造
public Country() {
super();
}
// 國家類的有參構造
public Country(String countryName, String gold, String sliver, String copper) {
super();
this.countryName = countryName;
this.gold = gold;
this.sliver = sliver;
this.copper = copper;
}
// get和set方法
public String getCountryName() {
return countryName;
}
public void setCountryName(String countryName) {
this.countryName = countryName;
}
public String getGold() {
return gold;
}
public void setGold(String gold) {
this.gold = gold;
}
public String getSliver() {
return sliver;
}
public void setSliver(String sliver) {
this.sliver = sliver;
}
public String getCopper() {
return copper;
}
public void setCopper(String copper) {
this.copper = copper;
}
public int getMedalSum() {
return Integer.parseInt(gold) + Integer.parseInt(sliver) + Integer.parseInt(copper);
}
// 重寫toString方法
@Override
public String toString() {
return "國家名字是: " + countryName + "\t金牌獎牌數是:" + gold + "\t銀牌數是:" + sliver + "\t銅牌數是:" + copper;
}
}
2.Check類
package cn.jason;
import java.util.Scanner;
/**
* 這是用於對信息校驗的類
*
* @blog http://blog.csdn.net/yan_yuhan
* @author Jason
* @version 1.2
* @2016年9月15日 上午0:41:13
*/
public class Check {
// 創建鍵盤錄入對象
private Scanner sc = new Scanner(System.in);
/**
* 這是校驗錄入的字符串是否爲符合中文要求
*/
public boolean judgeString(String countryName) {
// 定義匹配中文的正則表達式
String regex = "[\u4e00-\u9fa5]+";
// 對字符串進行校驗
if (!countryName.matches(regex)) {
System.out.println("你輸入的不符合要求,這是中文版系統,請輸入中文國家名稱:");
return false;
}
return true;
}
/**
* 這是校驗獎牌數量是不是數字的方法
*
* @param string
* 傳過來的參數
*/
public boolean judgeInteger(String string) {
// 定義匹配數字的正則表達式
String regex = "\\d+";
// 對字符串進行校驗
if (!string.matches(regex)) {
System.out.println("你輸入的不符合要求,這是中文版系統,請輸入中文國家名稱:");
return false;
}
return true;
}
}
3.OperationMethod類
package cn.jason;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.ListIterator;
import java.util.Scanner;
import java.util.TreeSet;
/**
* 這是用戶操作的類
*
* @blog http://blog.csdn.net/yan_yuhan
* @author Jason
* @version 1.2
* @2016年9月15日 上午0:41:13
*/
public class OperationMethod {
// 創建集合對象
// 這裏集合必須是靜態,靜態保證只要一個對象。如果不是靜態,多個類之間調用會出現多次創建集合對象,導致元素讀取異常。
public static List<Country> list = new ArrayList<Country>();
// 創建校驗類對象
private static Check check = new Check();
// 創建鍵盤錄入對象
private Scanner sc = new Scanner(System.in);
/**
* 這是添加國家信息的方法
* 分別對字符串進行校驗,如果校驗成功。那麼直接把國家的名稱、金牌、銀牌
* 銅牌的數量信息封裝到國家對象中,然後把國家對象存儲到集合中。
*/
public void addCountryIfo() {
// 錄入國家名稱
System.out.println("請輸入國家名稱:");
String countryName = sc.nextLine();
// 校驗字符串是否正確
if (!check.judgeString(countryName))
addCountryIfo();
// 查看錄入的信息是否重複
for (Country country : list) {
if (countryName.equals(country.getCountryName())) {
System.out.println("你添加的國家姓名已經存在");
addCountryIfo();
}
}
// 對金牌、銀牌、銅牌的校驗
boolean flag = false;
String gold = null;
String sliver = null;
String copper = null;
while (true) {
// 錄入金牌數量
System.out.println("請輸入金牌數量:");
gold = sc.nextLine();
// 對金牌的數據類型進行校驗
if (check.judgeInteger(gold))
break;
}
while (true) {
// 錄入銀牌數量
System.out.println("請輸入銀牌數量:");
sliver = sc.nextLine();
// 對銀牌的數據類型進行校驗
if (check.judgeInteger(sliver))
break;
}
while (true) {
// 錄入銅牌數量
System.out.println("請輸入銅牌數量:");
copper = sc.nextLine();
// 對銅牌的數據類型進行校驗
if (check.judgeInteger(copper))
break;
}
// 把國家信息封裝到國家對象中
Country c = new Country(countryName, gold, sliver, copper);
// 把封裝好的國家對象存儲到集合中
list.add(c);
// 調用繼續輸入菜單
continueInput();
}
/**
* 這是繼續輸入的方法
* 當提示是否繼續添加元素時,如果輸入"y",那麼調用添加功能繼續添加元素。 如果輸入"n",那麼調用返回上一級菜單。
* 否則進行信息錯誤提示,要求重新輸入。
*/
public void continueInput() {
System.out.println("是否繼續添加元素?y/n");
String choice = sc.nextLine();
if (choice.equalsIgnoreCase("y"))
// 調用增加元素的方法
addCountryIfo();
else if (choice.equalsIgnoreCase("n")) {
// 調用返回菜單
new Menu().returnMain();
} else {
System.out.println("你輸入有誤,請重新輸入");
// 調用再次輸入方法
continueInput();
}
}
/**
* 這是查找全部信息的方法
* 如果集合長度大於0,那麼輸出排好序的信息。否則進行錯誤提示。
*/
public void findAll() {
// 先對集合長度進行判斷
if (list.size() > 0)
// 如果長度大於0就遍歷集合,並且對元素按照金牌總數排序
SortMedal(list);
else
// 對錯誤信息進行提示
System.out.println("沒有任何國家信息");
//返回上一級菜單
new Menu().returnFindMenu();
}
/**
* 這是查詢奧運獎牌信息的方法
* 當提示是否要全部查看信息時,進行匹配字符串,如果是"y",那麼查看全部信息。 如果是"n",那麼進行逐個查看。
* 對集合長度判斷是否大於0,如果集合還沒有錄入數據,那麼不應該繼續輸入,所以進行校驗。
*/
public void findSingle() {
// 定義布爾標記
boolean flag = false;
do {
// 接收錄入數據
System.out.println("請輸入要查看國家的名稱:");
String newCountryName = sc.nextLine();
// 校驗字符串是否符合要求
if (check.judgeString(newCountryName)) {
flag = true;
}
if (list.size() > 0) {
// 遍歷集合
for (Country country : list) {
if (country.getCountryName().equals(newCountryName)) {
System.out.println(country);
flag = true;
break;
}
}
} else {
System.out.println("抱歉,沒有國家信息");
break;
}
// 提示是否繼續查看下一個國家信息
System.out.println("是否要繼續查看下一個國家信息?y/n");
String choice = sc.nextLine();
if (choice.equalsIgnoreCase("y"))
flag = false;
if (choice.equalsIgnoreCase("n"))
break;
else
System.out.println("你輸入有誤,請重新輸入");
} while (!flag);
//返回查詢菜單
new Menu().returnFindMenu();
// 調用返回主菜單方法
new Menu().returnMain();
}
/**
* 這是按照金牌總數排序的方法
* 先創建TreeSet集合對象,把list集合的數據存儲到TreeSet集合中排好序,
* 然後遍歷TreeSet集合輸出數據。
*/
public void SortMedal(List<Country> list) {
// 用TreeSet集合進行排序
TreeSet<Country> ts = new TreeSet<Country>(new Comparator<Country>() {
@Override
public int compare(Country o1, Country o2) {
return o2.getMedalSum() - o1.getMedalSum();
}
});
// 把list集合元素存儲到TreeSet集合
for (Country country : list) {
ts.add(country);
}
// 遍歷TreeSet集合,輸出數據
for (Country country : ts) {
System.out.println(country);
}
}
/**
* 這是修改金牌數量的方法
* 先對國家名稱進行校驗,校驗正確後錄入金牌的數量 然後遍歷集合進行移除原集合的信息,在添加新的金牌數量存儲到集合中
* 最後進行提示,修改成功,返回上一級菜單。
*/
public void modifyGold() {
// 接收校驗正確的國家名稱
String newCountryName = retrunCountryName();
String gold = null;
while (true) {
// 錄入金牌數量
System.out.println("請輸入金牌數量:");
gold = sc.nextLine();
// 校驗字符串
if (check.judgeInteger(gold))
break;
}
// 遍歷集合進行修改金牌數量
for (Country country:list) {
if (country.getCountryName().equals(newCountryName)) {
// 添加新的信息
country.setGold(gold);
break;
}
}
// 對修改操作進行提示
System.out.println("修改成功");
// 返回修改菜單
new Menu().returnModifyGoldMenu();
// 返回主菜單
new Menu().returnMain();
}
/**
* 這是修改銀牌數量的方法
* 先對國家名稱進行校驗,校驗正確後錄入金牌的數量 然後遍歷集合進行移除原集合的信息,在添加新的銀牌數量存儲到集合中
* 最後進行提示,修改成功,返回上一級菜單。
*/
public void modifySliver() {
// 拿到校驗好的國家名稱
String newCountryName = retrunCountryName();
String sliver = null;
while (true) {
// 錄入金牌數量
System.out.println("請輸入銀牌數量:");
sliver = sc.nextLine();
// 校驗字符串
if (check.judgeInteger(sliver))
break;
}
// 遍歷集合進行修改金牌數量
for (Country country:list) {
if (country.getCountryName().equals(newCountryName)) {
country.setSliver(sliver);
break;
}
}
System.out.println("修改成功");
// 返回修改菜單
new Menu().returnModifySliverMenu();
// 返回主菜單
new Menu().returnMain();
}
/**
* 這是修改銅牌數量的方法
* 先對國家名稱進行校驗,校驗正確後錄入金牌的數量 然後遍歷集合進行移除原集合的信息,在添加新的銅牌數量存儲到集合中
* 最後進行提示,修改成功,返回上一級菜單。
*/
public void modifyCopper() {
// 拿到校驗好的國家名稱
String newCountryName = retrunCountryName();
String copper = null;
while (true) {
// 錄入金牌數量
System.out.println("請輸入銅牌數量:");
copper = sc.nextLine();
// 校驗字符串
if (check.judgeInteger(copper))
break;
}
// 遍歷集合進行修改金牌數量
for (Country country:list) {
if (country.getCountryName().equals(newCountryName)) {
country.setCopper(copper);
break;
}
}
System.out.println("修改成功");
// 返回修改菜單
new Menu().returnModifyCopperMenu();
// 返回主菜單
new Menu().returnMain();
}
/**
* 這是對獎牌數量修改時,對重複代碼進行封裝的一個返回國家名稱方法
* 對金牌、銀牌、銅牌進行修改時,都要驗證國家名稱才能修改。
*
* @return 校驗好的國家名稱
*/
public String retrunCountryName() {
// 定義標記控制循環
boolean flag = false;
String newCountryName = null;
do {
System.out.println("請輸入要修改的國家名稱:");
newCountryName = sc.nextLine();
if (check.judgeString(newCountryName)) {
// 遍歷集合並且對國家名稱進行校驗
for (Country country : list) {
if (country.getCountryName().equals(newCountryName)) {
flag = true;
break;
}
}
if (!flag) {
// 對錯誤信息進行校驗
System.out.println("抱歉,你輸入的國家信息不存在");
// 返回修改菜單
new Menu().returnModifyGoldMenu();
// 返回主菜單
new Menu().returnMain();
}
}
} while (!flag);
return newCountryName;
}
/**
* 這是清除全部信息的方法
* 當要求輸入時,輸入"y",那麼清除全部信息。如果輸入"n",那麼返回清除菜單。否則進行錯誤提示,要求重新輸入。
* 此方法沒有管理員權限,所以可以直接清除。登錄註冊信息後續改進。
*
*
*
*
*/
public void clearAll() {
// 定義一個布爾標記
boolean flag = false;
do {
System.out.println("是否要清除全部信息?清除後不可恢復,請慎重。y/n");
String choice = sc.nextLine();
if (choice.equalsIgnoreCase("y")) {
// 如果是,那麼清除全部信息
list.clear();
flag = true;
// 清除提示
System.out.println("清除成功");
}
if (choice.equalsIgnoreCase("n")) {
flag = true;
}
if (!flag)
System.out.println("你輸入有誤,請重新輸入");
} while (!flag);
// 返回清除菜單
new Menu().returnClearMenu();
}
/**
* 這是清除單個奧運信息的方法
* 當提示是否要全部清除。當國家名稱匹配後進行清除。如果匹配不成功,那麼進行錯誤提示,要求重新輸入。
* 然後進行下一步操作
*/
public void clearSingle() {
// 定義一個布爾標記
boolean flag = false;
String newCountryName = null;
while (true) {
// 接收信息提示
System.out.println("請輸入要清除的國家名稱:");
newCountryName = sc.nextLine();
// 對字符串進行校驗
if (check.judgeString(newCountryName))
break;
}
// 對修改後的操作進行提示
for (Country country : list) {
if (country.getCountryName().equals(newCountryName)) {
// 清除當前國家對象
list.remove(country);
System.out.println("清除成功");
flag = true;
break;
}
}
// 如果沒有匹配成功,那麼對錯誤信息進行提示
if (!flag)
System.out.println("你輸入有誤,沒有此信息");
// 返回清除菜單
new Menu().returnClearMenu();
// 返回主菜單
new Menu().returnMain();
}
}
4.Menu類
package cn.jason;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import java.util.Scanner;
/**
* 這是系統所有菜單的類
*
* @blog http://blog.csdn.net/yan_yuhan
* @author Jason
* @version 1.2
* @2016年9月15日 上午0:41:13
*/
public class Menu {
// 創建鍵盤錄入對象
private Scanner sc = new Scanner(System.in);
// 創建操作類對象
private static OperationMethod om = new OperationMethod();
/**
* 這是主菜單的方法 分別顯示五級菜單供客戶選擇。
*/
public void mainMenu() {
System.out.println("**-------------歡迎來到奧運獎牌中文信息系統-------------**\n");
System.out.println("\t\t1.添加奧運獎牌信息\n");
System.out.println("\t\t2.查看奧運獎牌信息\n");
System.out.println("\t\t3.修改奧運獎牌信息\n");
System.out.println("\t\t4.刪除奧運獎牌信息\n");
System.out.println("\t\t5.退出系統");
System.out.println("請選擇:");
// 調用二級菜單
secondMenu();
}
/**
* 這是根據主菜單做出相應選擇的菜單
* 對用戶的選擇進行判斷,分別執行不同的功能模塊。
*/
public void secondMenu() {
// 創建標記
boolean flag = false;
do {
// 接收錄入的數據
String choice = sc.nextLine();
// 對選擇進行switch語句判斷
switch (choice) {
case "1":
// 調用添加元素的方法
om.addCountryIfo();
break;
case "2":
// 調用查詢菜單
findMenu();
break;
case "3":
// 調用修改菜單
modifyMenu();
break;
case "4":
// 調用清除菜單
clearMenu();
break;
case "5":
// 退出系統提示
System.out.println("歡迎使用奧運獎牌信息系統");
break;
default:
//對錯誤信息提示
System.out.println("你輸入有誤,請重新輸入");
flag = true;
break;
}
} while (flag);
}
/**
* 這是查找信息的菜單
* 根據用戶的選擇進行執行相關模塊
*/
public void findMenu() {
System.out.println("**-------------查看奧運獎牌信息>查看方式-------------**\n");
System.out.println("\t\t1.全部查看\n");
System.out.println("\t\t2.部分查看\n");
System.out.println("請選擇,輸入數字或按'n'返回上一級菜單:");
// 對用戶的選擇進行判斷,分別執行不同的功能模塊。
findSecondMenu();
}
/**
* 這是查找菜單的子菜單的方法
* 對用戶的選擇進行判斷,分別執行不同的功能模塊。
*/
public void findSecondMenu() {
// 定義標記控制循環
boolean flag = false;
do {
// 接收錄入的數據
String choice = sc.nextLine();
// 對選擇進行選擇性判斷,並執行不同的模塊
switch (choice) {
case "1":
//執行全部查找,並且按照獎牌總數排序
om.findAll();
break;
case "2":
//調用單個查找方法
om.findSingle();
break;
case "n":
// 返回主菜單
mainMenu();
break;
default:
// 進行錯誤提示
System.out.println("你輸入有誤,請重新輸入");
flag = true;
break;
}
} while (flag);
}
/**
* 這是返回查找菜單的方法
* 如果輸入"y",那麼返回查找菜單,如果是"n",那麼返回主菜單,否則輸入有誤,要求重新輸入
*/
public void returnFindMenu() {
// 定義標記
boolean flag = false;
System.out.println("是否返回查看菜單?y/n");
String choice = sc.nextLine();
if (choice.equalsIgnoreCase("y"))
findMenu();
// 如果是,返回主菜單
else if (choice.equalsIgnoreCase("n")) {
// 如果不是,那麼繼續進行單個清除
returnMain();
} else {
// 對錯誤信息進行提示
System.out.println("你輸入有誤,請重新輸入");
returnFindMenu();
}
}
/**
* 這是修改奧運獎牌信息的子菜單
* 根據用戶的選擇,執行相應的模塊
*/
public void modifyMenu() {
System.out.println("**-------------修改奧運獎牌信息>修改方式-------------**\n");
System.out.println("\t\t1.修改金牌數量\n");
System.out.println("\t\t2.修改銀牌數量\n");
System.out.println("\t\t3.修改銅牌數量\n");
System.out.println("請選擇,輸入數字或按'n'返回上一級菜單:");
// 對用戶的選擇進行判斷,分別執行不同的功能模塊。
modifySecondMenu();
}
/**
* 這是對修改菜單進行相應操作的方法
* 對用戶的選擇進行判斷,分別執行不同的功能模塊。
*/
public void modifySecondMenu() {
// 定義標記控制循環
boolean flag = false;
do {
// 接收錄入的數據
String choice = sc.nextLine();
// 對選擇進行選擇性判斷,並執行不同的模塊
switch (choice) {
case "1":
// 調用修改金牌數量功能
om.modifyGold();
break;
case "2":
// 調用修改銀牌數量功能
om.modifySliver();
break;
case "3":
// 調用修改銅牌數量功能
om.modifyCopper();
break;
case "n":
// 返回主菜單
mainMenu();
break;
default:
// 進行錯誤提示
System.out.println("你輸入有誤,請重新輸入");
flag = true;
break;
}
} while (flag);
}
/**
* 這是判斷是否返回修改金牌數量的菜單
*/
public void returnModifyGoldMenu() {
// 定義布爾標記
boolean flag = false;
System.out.println("是否返回修改菜單?y/n");
String choice = sc.nextLine();
if (choice.equalsIgnoreCase("y"))
// 如果是,返回修改主菜單
modifyMenu();
else if (choice.equalsIgnoreCase("n")) {
// 如果不是返回修改菜單,繼續進行修改金牌數量
om.modifyGold();
} else {
// 對錯誤進行提示
System.out.println("你輸入有誤,請重新輸入");
returnModifyGoldMenu();
}
}
/**
* 這是判讀是否返回修改銀牌數量的菜單
*/
public void returnModifySliverMenu() {
// 定義標記
boolean flag = false;
System.out.println("是否返回修改菜單?y/n");
String choice = sc.nextLine();
if (choice.equalsIgnoreCase("y"))
// 如果是,返回修改主菜單
modifyMenu();
else if (choice.equalsIgnoreCase("n")) {
// 如果不是,繼續進項銀牌數量修改功能
om.modifySliver();
} else {
// 對錯誤信息進行提示
System.out.println("你輸入有誤,請重新輸入");
returnModifySliverMenu();
}
}
/**
* 這是判斷是否返回修改銅牌數量的菜單
*/
public void returnModifyCopperMenu() {
// 定義標記
boolean flag = false;
System.out.println("是否返回修改菜單?y/n");
String choice = sc.nextLine();
if (choice.equalsIgnoreCase("y"))
// 如果是,返回修改主菜單
modifyMenu();
else if (choice.equalsIgnoreCase("n")) {
// 如果不是,繼續進行銅牌數量的修改
om.modifyCopper();
} else {
// 對錯誤信息進行提示
System.out.println("你輸入有誤,請重新輸入");
returnModifyCopperMenu();
}
}
/**
* 這是清除菜單的子菜單
* 根據用戶不同的選擇,執行相應的模塊
*/
public void clearMenu() {
System.out.println("**-------------刪除奧運獎牌信息>刪除方式-------------**\n");
System.out.println("\t\t1.清除全部信息\n");
System.out.println("\t\t2.清除單個信息\n");
System.out.println("請選擇,輸入數字或按'n'返回上一級菜單:");
// 調用二級菜單
clearSecondMenu();
}
/**
* 這是清除菜單執行方式的方法
* 根據不同的選擇,執行相應的功能
*/
public void clearSecondMenu() {
// 定義標記控制循環
boolean flag = false;
do {
// 接收錄入的數據
String choice = sc.nextLine();
// 對選擇進行選擇性判斷,並執行不同的模塊
switch (choice) {
case "1":
//調用全部清除功能
om.clearAll();
break;
case "2":
//調用單個清除的功能
om.clearSingle();
break;
case "n":
// 返回主菜單
mainMenu();
break;
default:
// 進行錯誤提示
System.out.println("你輸入有誤,請重新輸入");
flag = true;
break;
}
} while (flag);
}
/**
* 這是是否返回清除菜單的方法
* 如果輸入"y",那麼返回清除菜單。如果是"n",那麼返回主菜單
* 否則進行錯誤提示,要求重新輸入。
*/
public void returnClearMenu() {
// 定義標記
boolean flag = false;
System.out.println("是否返回清除菜單?y/n");
String choice = sc.nextLine();
if (choice.equalsIgnoreCase("y"))
// 如果是,返回主菜單
clearMenu();
else if (choice.equalsIgnoreCase("n")) {
// 如果不是,那麼繼續進行當個清除
returnMain();
} else {
// 對錯誤信息進行提示
System.out.println("你輸入有誤,請重新輸入");
returnClearMenu();
}
}
/**
* 這是返回上主菜單的方法
* 當提示是否返回上一級菜單時,如果輸入"y",那麼直接返回主菜單。 如果輸入"n",那麼直接退出系統
*/
public void returnMain() {
// 定義標記
boolean flag = false;
System.out.println("是否返回主菜單?y/n");
String choice = sc.nextLine();
if (choice.equalsIgnoreCase("y"))
// 如果是,返回主菜單
mainMenu();
else if (choice.equalsIgnoreCase("n")) {
// 如果不是,退出系統
System.out.println("歡迎使用奧運獎牌信息系統");
} else {
// 對錯誤信息進行提示
System.out.println("你輸入有誤,請重新輸入");
returnMain();
}
}
}
5.StartSMS類
package cn.jason;
/**
* 這是系統啓動類
*
* @blog http://blog.csdn.net/yan_yuhan
* @author Jason
* @version 1.2
* @2016年9月15日 上午0:46:52
*/
public class StartSMS {
public static void main(String[] args) {
// 創建菜單對象
Menu menu = new Menu();
// 調用主菜單
menu.mainMenu();
}
}
四.案例截圖
五.歸納總結
1.類中多次使用的對象可以以靜態成員變量出現在成員位置。兩個類中的成員位置要是創建對象,不能相互調用。否則會出現每一次調用每一次重新創建對象,尤其是集合會出現信息讀寫異常。
2.功能方法獨立封裝
多個功能要多次使用就單獨封裝一個方法,避免方法亂用,導致代碼不明確。如多級菜單返回,單獨封裝返回菜單。