奥运奖牌中文信息系统

来源:互联网 发布:mac如何打出拼音声调 编辑:程序博客网 时间:2024/05/17 04:01

一.案例说明


本案例并主要是对集合的综合运用,并且实现集合的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方法@Overridepublic 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;elseSystem.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>() {@Overridepublic 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.功能方法独立封装

多个功能要多次使用就单独封装一个方法,避免方法乱用,导致代码不明确。如多级菜单返回,单独封装返回菜单



0 0
原创粉丝点击