Java第三次博客
1.前言
(1)题量、难度:
期中考试后做了很多题目,但是给的时间也是充足的,除了最后几个星期因为提早放假导致考试提前,所以后期代码写的时间很短,基本都是赶出来的,写的质量并不是很好。
这段时间除了做了一些比较短的题目以外,一直在不断完善的代码就是电信计费以及农夫过河问题了。这两道题也不会很难,对比之前的多边形系列的题,电信计费还是很好写的,就是写的时候因为类有点多,刚开始写的时候会很绕。
大作业六到大作业八包括了电信计费这个系列的题,一次作业实现一个功能,一共是三个功能。
实验二到实验五一直都是在写农夫过河这个问题,从易到难,最后的实验五直接在之前的基础上写出了这个游戏的界面,个人认为虽然这个界面可能并不是那么难实现,但是因为刚接触的原因,写实验的时候边写边学,花费了大量的时间。但最后也算是写完了。
(2)知识点:
对super关键字的使用、理解继承与组合的区别、实现代码的复用,使得可读性增加。
java语言中多态的基本概念及使用方法以及抽象类和接口的基本概念和使用方法。在写实验四的时候还去学习了一下单例模式,基本了解并掌握其用法。
使用javafx来创建图形界面。
对类的封装。
2.设计与分析
(1)电信计费1
核心代码:
1 public class Main { 2 3 public static void main(String[] args) { 4 5 Scanner sc = new Scanner(System.in); 6 7 String regex1 = "u\\-0791\\d{7,8}\\s0"; 8 // String regex2 = "u\\-\\d{11}\\s[12]"; 9 String regex3 = "t\\-0791\\d{7,8}\\s\\d{10,12}(\\s([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]|[0-9][1-9][0-9]{2}|[1-9][0-9]{3})\\.((((0?[13578])|(1[02]))\\.((0?[1-9])|([12][0-9])|(3[01])))|(0?2\\.((0?[1-9])|(1[0-9])|(2[0-9])))|(((0?[469])|(11))\\.((0?[1-9])|([12][0-9])|(30))))\\s(([01][0-9])|(2[0-3]))(\\:([0-5][0-9])){2}){2}"; //座机呼叫座机 10 // String regex4 = ""; //座机打手机 11 // String regex5 = ""; //手机打座机 12 // String regex6 = ""; //手机打手机 13 14 15 String s = sc.nextLine(); 16 String[] msg,msg1; 17 List<User> user = new ArrayList<>(); 18 19 for(int i = 0;!s.equals("end");i++) { 20 if(s.matches(regex1)) { 21 msg = s.split("\\-|\\s"); 22 boolean flag = true; 23 for(User u:user) { 24 if(u.getNumber().equals(msg[1])) { 25 flag = false; 26 break; 27 } 28 } 29 if(flag) { 30 user.add(new User(msg[1])); 31 choiceWay(user.get(user.size()-1),msg[2]); 32 } 33 } 34 if(s.matches(regex3)) { 35 msg1 = s.split("\\-|\\s"); 36 String[] time; 37 time = msg1[3].split("\\."); 38 int year = Integer.parseInt(time[0]); 39 int month = Integer.parseInt(time[1]); 40 int day = Integer.parseInt(time[2]); 41 if(month == 2) { 42 if(!leapYear(year) && day == 29) { 43 44 } 45 } 46 else { 47 Date d1 = change(msg1[3],msg1[4]); 48 Date d2 = change(msg1[5],msg1[6]); 49 CallRecord callRecord = new CallRecord(msg1[1],msg1[2],d1,d2,"0791",msg1[2].substring(0, 4)); 50 saveRecord(user,callRecord); 51 } 52 } 53 s = sc.nextLine(); 54 55 } 56 Collections.sort(user, new SortByNum()); //对号码排序 57 for(User u:user) { 58 double sum = u.getChargeMode().calCost(u.getUserRecords(),u.getChargeMode().getChargeRules()); 59 double month = u.getChargeMode().getMonthlyRent(); 60 double cost = u.calCost(sum,month); 61 double balance = u.calBalance(cost); 62 System.out.println(u.getNumber()+" "+sum+" "+balance); //计算每个用户的话费总额 63 } 64 65 sc.close(); 66 } 67 68 public static boolean leapYear(int year) { 69 if((year%4==0 && year%100!=0) || (year%400==0)) 70 return true; 71 return false; 72 73 } 74 75 public static void choiceWay(User user,String s) { //选择计费方式 76 if(s.equals("0")) { 77 user.setChargeMode(new LandlinePhoneCharging()); 78 user.getChargeMode().getChargeRules().add(new LandPhoneInCityRule()); 79 user.getChargeMode().getChargeRules().add(new LandPhoneInProvinceRule()); 80 user.getChargeMode().getChargeRules().add(new LandPhoneInLandRule()); 81 } 82 } 83 84 public static void saveRecord(List<User> user,CallRecord callRecord) { //储存通讯记录 85 86 for(User u:user) { 87 if(u.getNumber().matches(callRecord.callingNumber)) { 88 if(callRecord.getStartTime().compareTo(callRecord.getEndTime())<=0) { 89 u.getUserRecords().addCallingInCityRecords(callRecord); 90 } 91 } 92 } 93 94 } 95 96 public static Date change(String s1,String s2) { //日期格式转换 97 SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); 98 String s = s1+" "+s2; 99 Date date = null; 100 try { 101 date = simpleDateFormat.parse(s); 102 } catch (ParseException e) { 103 e.printStackTrace(); 104 } 105 return date; 106 } 107 } 108 109 class SortByNum implements Comparator{ 110 111 @Override 112 public int compare(Object o1, Object o2) { 113 User s1 = (User) o1; 114 User s2 = (User) o2; 115 Long a1 = Long.parseLong(s1.getNumber()); 116 Long a2 = Long.parseLong(s2.getNumber()); 117 if (a1 > a2) 118 return 1; 119 return -1; 120 121 } 122 123 }
SourceMonitor报表:

写这个题刚开始就是去分析这写给出了的类,哪个类代表着什么功能,什么意思,如何再顺着给出的类图去一个一个写,我是先把所有的类都差不多写完了,再去开始写主类调用方法,然后再根据主类去调整修改调用的方法代码。
先把所有的类创建好后,根据老师给的第一张类图先把ChargeMode类和座机收费类给写掉,然后去看第二张类图的通讯记录类,期中电话记录和短信记录作为其子类,但是本题因为只实现座机通过话功能,所以暂时用不上短信记录。然后第三张类图是给了一个计费类,根据拨号号码所在地去计算费用,类图给了三个类,分别是LandPhoneInCityRule、LandPhoneInProvinceRule、LandPhoneInLandRule,但是一开始我以为这三个类是座机分别拨打本地,省内,外地的收费方式。但是后面发现这么写并不方便,这个到分析第二题的时候再说。
这个题感觉难的地方一个是运用集合框架去实现排序,因为之前没用过,还有各种数据的传递,需要对每个类代表什么很熟悉。然后写主类的时候,输入一列信息,然后根据正则表达式去判断是开户信息,还是通话记录,然后根据不同的信息去存入不同链表中以方便后续的调用。然后信息录入完了后,先用Collections对链表根据电话号码从小到大排序,然后就遍历用户链表去输出每个用户的账单。
写判断通话记录合法性的正则表达式的时候因为对每个号码及时间的判断,所以需要不断修改,但是又因为正则表达式一连串的,所以修改起来很麻烦。所以就导致一开始去测试的时候有很多测试点都无法通过。
(2)电信计费2
核心代码:
1 package pta73; 2 3 import java.text.ParseException; 4 import java.text.SimpleDateFormat; 5 import java.util.ArrayList; 6 import java.util.Collections; 7 import java.util.Comparator; 8 import java.util.Date; 9 import java.util.List; 10 import java.util.Scanner; 11 12 public class Main { 13 14 public static void main(String[] args) { 15 16 Scanner sc = new Scanner(System.in); 17 18 String regex = "((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]|[0-9][1-9][0-9]{2}|[1-9][0-9]{3})\\.(((0?[13578]|1[02])\\.(0?" + 19 "[1-9]|[12][0-9]|3[01]))|(([469]|11)\\.([1-9]|[12][0-9]|30))|(2\\.([1-9]|[1][0-9]|2[0-8]))))|(((" + 20 "[0-9]{2})([48]|[2468][048]|[13579][26])|(([48]|[2468][048]|[3579][26])00))\\.2\\.29))" + 21 "\\s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])\\s" + 22 "((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]|[0-9][1-9][0-9]{2}|[1-9][0-9]{3})\\.((([13578]|1[02])\\.(" + 23 "[1-9]|[12][0-9]|3[01]))|(([469]|11)\\.([1-9]|[12][0-9]|30))|(2\\.([1-9]|[1][0-9]|2[0-8]))))|(((" + 24 "[0-9]{2})([48]|[2468][048]|[13579][26])|(([48]|[2468][048]|[3579][26])00))\\.2\\.29))" + 25 "\\s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])"; //判断时间 26 String regex1 = "[u]-0791\\d{7,8}\\s0"; 27 String regex2 = "[u]-1\\d{10}\\s[12]"; 28 String regex3 = "[t]-0791[0-9]{7,8}\\s" + "0[0-9]{9,11}\\s" + regex; //座机呼叫座机 29 String regex4 = "[t]-0791[0-9]{7,8}\\s" + "1[0-9]{10}\\s" + "0[0-9]{2,3}\\s" + regex; //座机打手机 30 String regex5 = "[t]-1[0-9]{10}\\s" + "0[0-9]{2,3}\\s" + "0[0-9]{9,11}\\s" + regex; //手机打座机 31 String regex6 = "[t]-1[0-9]{10}\\s" + "0[0-9]{2,3}\\s" + "1[0-9]{10}\\s" + "0[0-9]{2,3}\\s" + regex; //手机打手机 32 String regex7 = "[m]-1[0-9]{10}\\s" + "1[0-9]{10}\\s" + "[A-Za-z0-9\\s\\,\\.]*"; //发短信 33 34 String s = sc.nextLine(); 35 String[] msg,msg1; 36 List<User> user = new ArrayList<>(); 37 38 for(int i = 0;!s.equals("end");i++) { 39 if(s.matches(regex1)) { 40 msg = s.split("\\-|\\s"); 41 boolean flag = true; 42 for(User u:user) { 43 if(u.getNumber().equals(msg[1])) { 44 flag = false; 45 break; 46 } 47 } 48 if(flag) { 49 user.add(new User(msg[1])); 50 choiceWay(user.get(user.size()-1),msg[2]); 51 } 52 } 53 else if(s.matches(regex2)) { 54 msg = s.split("\\-|\\s"); 55 boolean flag = true; 56 for(User u:user) { 57 if(u.getNumber().equals(msg[1])) { 58 flag = false; 59 break; 60 } 61 } 62 if(flag) { 63 user.add(new User(msg[1])); 64 choiceWay(user.get(user.size()-1),msg[2]); 65 } 66 } 67 if(s.matches(regex3)) { 68 msg1 = s.split("\\-|\\s"); 69 Date d1 = change(msg1[3],msg1[4]); 70 Date d2 = change(msg1[5],msg1[6]); 71 CallRecord callRecord = new CallRecord(msg1[1],msg1[2],d1,d2,"0791",msg1[2].substring(0, 4)); 72 saveRecord(user,callRecord); 73 } 74 else if(s.matches(regex4)) { 75 msg1 = s.split("\\-|\\s"); 76 Date d1 = change(msg1[4],msg1[5]); 77 Date d2 = change(msg1[6],msg1[7]); 78 CallRecord callRecord = new CallRecord(msg1[1],msg1[2],d1,d2,"0791",msg1[3]); 79 saveRecord(user,callRecord); 80 } 81 else if(s.matches(regex5)) { 82 msg1 = s.split("\\-|\\s"); 83 Date d1 = change(msg1[4],msg1[5]); 84 Date d2 = change(msg1[6],msg1[7]); 85 CallRecord callRecord = new CallRecord(msg1[1],msg1[3],d1,d2,msg1[2],msg1[3].substring(0, 4)); 86 saveRecord(user,callRecord); 87 } 88 else if(s.matches(regex6)) { 89 msg1 = s.split("\\-|\\s"); 90 Date d1 = change(msg1[5],msg1[6]); 91 Date d2 = change(msg1[7],msg1[8]); 92 CallRecord callRecord = new CallRecord(msg1[1],msg1[3],d1,d2,msg1[2],msg1[4]); 93 saveRecord(user,callRecord); 94 } 95 if(s.matches(regex7)) { 96 msg1 = s.split("\\-|\\s"); 97 MessageRecord messageRecord = new MessageRecord(msg1[1],msg1[2],msg1[3]); 98 saveRecord(user,messageRecord); 99 } 100 101 s = sc.nextLine(); 102 103 } 104 Collections.sort(user, new SortByNum()); //对号码排序 105 for(User u:user) { 106 double sum = u.getChargeMode().calCost(u.getUserRecords(),u.getChargeMode().getChargeRules()); 107 double month = u.getChargeMode().getMonthlyRent(); 108 double cost = u.calCost(sum,month); 109 double balance = u.calBalance(cost); 110 System.out.println(u.getNumber()+" "+sum+" "+balance); //计算每个用户的话费总额 111 } 112 113 sc.close(); 114 } 115 116 public static void choiceWay(User user,String s) { //选择计费方式 117 if(s.equals("0")) { 118 user.setChargeMode(new LandlinePhoneCharging()); 119 user.getChargeMode().getChargeRules().add(new LandPhoneInCityRule()); 120 user.getChargeMode().getChargeRules().add(new LandPhoneInProvinceRule()); 121 user.getChargeMode().getChargeRules().add(new LandPhoneInLandRule()); 122 } 123 else if(s.equals("1")) { 124 user.setChargeMode(new MobilePhoneCharging()); 125 user.getChargeMode().getChargeRules().add(new MobliePhoneInCityRule()); 126 user.getChargeMode().getChargeRules().add(new MobliePhoneInProvinceRule()); 127 user.getChargeMode().getChargeRules().add(new MobliePhoneInLandRule()); 128 user.getChargeMode().getChargeRules().add(new MobilePhoneAnswering()); 129 // user.getChargeMode().getChargeRules().add(new ) 短信方法 130 } 131 } 132 133 public static void saveRecord(List<User> user,CallRecord callRecord) { //储存通讯记录 134 135 for(User u:user) { 136 if(u.getNumber().matches(callRecord.callingNumber)) { 137 if(callRecord.getStartTime().compareTo(callRecord.getEndTime())<=0) { 138 if(callRecord.getCallingAddressAreaCode().matches("0791")) 139 u.getUserRecords().addCallingInCityRecords(callRecord); 140 else if(callRecord.getCallingAddressAreaCode().matches("0790|079[2-9]|0701")) 141 u.getUserRecords().addCallingInProvinceRecords(callRecord); 142 else 143 u.getUserRecords().addCallingInLandRecords(callRecord); 144 } 145 } 146 if(u.getNumber().matches(callRecord.answerNumber)) { 147 if(callRecord.getStartTime().compareTo(callRecord.getEndTime())<=0) { 148 if(callRecord.getAnswerAddressAreaCode().matches("0791")) { 149 u.getUserRecords().addAnswerInCityRecords(callRecord); 150 } 151 else if(callRecord.getAnswerAddressAreaCode().matches("0790|079[2-9]|0701")) { 152 u.getUserRecords().addAnswerInProvinceRecords(callRecord); 153 } 154 else { 155 u.getUserRecords().addAnswerInLandRecords(callRecord); 156 } 157 } 158 } 159 } 160 } 161 public static void saveRecord(List<User> user,MessageRecord messageRecord) { //储存短信记录 162 163 for(User u:user) { 164 if(u.getNumber().matches(messageRecord.callingNumber)) { 165 u.getUserRecords().addSendMessageRecords(messageRecord); 166 } 167 if(u.getNumber().matches(messageRecord.answerNumber)) { 168 u.getUserRecords().addReceiveMessageRecords(messageRecord); 169 } 170 } 171 } 172 173 174 public static Date change(String s1,String s2) { //日期格式转换 175 SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); 176 String s = s1+" "+s2; 177 Date date = null; 178 try { 179 date = simpleDateFormat.parse(s); 180 } catch (ParseException e) { 181 e.printStackTrace(); 182 } 183 return date; 184 } 185 } 186 187 class SortByNum implements Comparator{ 188 189 @Override 190 public int compare(Object o1, Object o2) { 191 User s1 = (User) o1; 192 User s2 = (User) o2; 193 Long a1 = Long.parseLong(s1.getNumber()); 194 Long a2 = Long.parseLong(s2.getNumber()); 195 String m1 = a1.toString(); 196 String m2 = a2.toString(); 197 int result = 0; 198 199 if(m1.charAt(0)-m2.charAt(0)<0) { 200 return 1; 201 } 202 else if(m1.charAt(0)-m2.charAt(0)==0){ 203 for(int i = 1;i<m1.length() && i<m2.length();i++) { 204 result = m1.charAt(i)-m2.charAt(i); 205 if(result > 0) { 206 return 1; 207 } 208 } 209 } 210 return -1; 211 } 212 213 }
SourceMonitor报表:

这个题就是在第一题的基础上多加了一个手机计费功能,在这个类里就要考虑手机拨打电话是所在地区,也就是说如果我的计费类跟第一题一样写的话,我需要创建九个子类去实现计费。所以在写第二题的时候我就把第一题的LandPhoneInCityRule、LandPhoneInProvinceRule、LandPhoneInLandRule的计费方式全部写到LandPhoneInCityRule了里面去了,也就是说LandPhoneInCityRule不是座机在市内拨打市内号码,而是座机在市内拨打任意地方的号码,然后在计费方法内再去判断拨打的电话的号码的地区及收费价格,然后还能将被拨打的电话的这条记录存进接听电话类这个链表内。
写这个功能的时候唯一觉得难写的就是输入信息合法性的正则表达式的判断,怎么写都会出问题,然后参考了一下同学的正则表达式才过了测试点。
(3)电信计费3
核心代码:
1 package pta8; 2 3 import java.text.ParseException; 4 import java.text.SimpleDateFormat; 5 import java.util.ArrayList; 6 import java.util.Collections; 7 import java.util.Comparator; 8 import java.util.Date; 9 import java.util.List; 10 import java.util.Scanner; 11 12 public class Main { 13 14 public static void main(String[] args) { 15 16 Scanner sc = new Scanner(System.in); 17 18 String regex = "((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]|[0-9][1-9][0-9]{2}|[1-9][0-9]{3})\\.(((0?[13578]|1[02])\\.(0?" + 19 "[1-9]|[12][0-9]|3[01]))|(([469]|11)\\.([1-9]|[12][0-9]|30))|(2\\.([1-9]|[1][0-9]|2[0-8]))))|(((" + 20 "[0-9]{2})([48]|[2468][048]|[13579][26])|(([48]|[2468][048]|[3579][26])00))\\.2\\.29))" + 21 "\\s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])\\s" + 22 "((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]|[0-9][1-9][0-9]{2}|[1-9][0-9]{3})\\.((([13578]|1[02])\\.(" + 23 "[1-9]|[12][0-9]|3[01]))|(([469]|11)\\.([1-9]|[12][0-9]|30))|(2\\.([1-9]|[1][0-9]|2[0-8]))))|(((" + 24 "[0-9]{2})([48]|[2468][048]|[13579][26])|(([48]|[2468][048]|[3579][26])00))\\.2\\.29))" + 25 "\\s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])"; //判断时间 26 String regex1 = "[u]-0791\\d{7,8}\\s0"; 27 String regex2 = "[u]-1\\d{10}\\s[123]"; 28 String regex3 = "[t]-0791[0-9]{7,8}\\s" + "0[0-9]{9,11}\\s" + regex; //座机呼叫座机 29 String regex4 = "[t]-0791[0-9]{7,8}\\s" + "1[0-9]{10}\\s" + "0[0-9]{2,3}\\s" + regex; //座机打手机 30 String regex5 = "[t]-1[0-9]{10}\\s" + "0[0-9]{2,3}\\s" + "0[0-9]{9,11}\\s" + regex; //手机打座机 31 String regex6 = "[t]-1[0-9]{10}\\s" + "0[0-9]{2,3}\\s" + "1[0-9]{10}\\s" + "0[0-9]{2,3}\\s" + regex; //手机打手机 32 String regex7 = "[m]-1[0-9]{10}\\s" + "1[0-9]{10}\\s" + "[A-Za-z0-9\\s\\,\\.]*"; //发短信 33 34 String s = sc.nextLine(); 35 String[] msg,msg1; 36 List<User> user = new ArrayList<>(); 37 38 for(int i = 0;!s.equals("end");i++) { 39 if(s.matches(regex1)) { 40 msg = s.split("\\-|\\s"); 41 boolean flag = true; 42 for(User u:user) { 43 if(u.getNumber().equals(msg[1])) { 44 flag = false; 45 break; 46 } 47 } 48 if(flag) { 49 user.add(new User(msg[1])); 50 choiceWay(user.get(user.size()-1),msg[2]); 51 } 52 } 53 else if(s.matches(regex2)) { 54 msg = s.split("\\-|\\s"); 55 boolean flag = true; 56 for(User u:user) { 57 if(u.getNumber().equals(msg[1])) { 58 flag = false; 59 break; 60 } 61 } 62 if(flag) { 63 user.add(new User(msg[1])); 64 choiceWay(user.get(user.size()-1),msg[2]); 65 } 66 } 67 if(s.matches(regex3)) { 68 msg1 = s.split("\\-|\\s"); 69 Date d1 = change(msg1[3],msg1[4]); 70 Date d2 = change(msg1[5],msg1[6]); 71 CallRecord callRecord = new CallRecord(msg1[1],msg1[2],d1,d2,"0791",msg1[2].substring(0, 4)); 72 saveRecord(user,callRecord); 73 } 74 else if(s.matches(regex4)) { 75 msg1 = s.split("\\-|\\s"); 76 Date d1 = change(msg1[4],msg1[5]); 77 Date d2 = change(msg1[6],msg1[7]); 78 CallRecord callRecord = new CallRecord(msg1[1],msg1[2],d1,d2,"0791",msg1[3]); 79 saveRecord(user,callRecord); 80 } 81 else if(s.matches(regex5)) { 82 msg1 = s.split("\\-|\\s"); 83 Date d1 = change(msg1[4],msg1[5]); 84 Date d2 = change(msg1[6],msg1[7]); 85 CallRecord callRecord = new CallRecord(msg1[1],msg1[3],d1,d2,msg1[2],msg1[3].substring(0, 4)); 86 saveRecord(user,callRecord); 87 } 88 else if(s.matches(regex6)) { 89 msg1 = s.split("\\-|\\s"); 90 Date d1 = change(msg1[5],msg1[6]); 91 Date d2 = change(msg1[7],msg1[8]); 92 CallRecord callRecord = new CallRecord(msg1[1],msg1[3],d1,d2,msg1[2],msg1[4]); 93 saveRecord(user,callRecord); 94 } 95 if(s.matches(regex7)) { 96 MessageRecord messageRecord = new MessageRecord(s.substring(2, 13),s.substring(14, 25),s.substring(26)); 97 saveRecord(user,messageRecord); 98 } 99 100 s = sc.nextLine(); 101 102 } 103 Collections.sort(user, new SortByNum()); //对号码排序 104 for(User u:user) { 105 double sum = u.getChargeMode().calCost(u.getUserRecords(),u.getChargeMode().getChargeRules()); 106 double month = u.getChargeMode().getMonthlyRent(); 107 double cost = u.calCost(sum,month); 108 double balance = u.calBalance(cost); 109 System.out.println(u.getNumber()+" "+sum+" "+balance); //计算每个用户的话费总额 110 } 111 112 sc.close(); 113 } 114 115 public static void choiceWay(User user,String s) { //选择计费方式 116 if(s.equals("0")) { 117 user.setChargeMode(new LandlinePhoneCharging()); 118 user.getChargeMode().getChargeRules().add(new LandPhoneInCityRule()); 119 user.getChargeMode().getChargeRules().add(new LandPhoneInProvinceRule()); 120 user.getChargeMode().getChargeRules().add(new LandPhoneInLandRule()); 121 } 122 else if(s.equals("1")) { 123 user.setChargeMode(new MobilePhoneCharging()); 124 user.getChargeMode().getChargeRules().add(new MobliePhoneInCityRule()); 125 user.getChargeMode().getChargeRules().add(new MobliePhoneInProvinceRule()); 126 user.getChargeMode().getChargeRules().add(new MobliePhoneInLandRule()); 127 user.getChargeMode().getChargeRules().add(new MobilePhoneAnswering()); 128 } 129 else if(s.equals("3")) { 130 user.setChargeMode(new MessageCharing()); 131 user.getChargeMode().getChargeRules().add(new SendMessageRule()); 132 } 133 } 134 135 public static void saveRecord(List<User> user,CallRecord callRecord) { //储存通讯记录 136 137 for(User u:user) { 138 if(u.getNumber().matches(callRecord.callingNumber)) { 139 if(callRecord.getStartTime().compareTo(callRecord.getEndTime())<=0) { 140 if(callRecord.getCallingAddressAreaCode().matches("0791")) 141 u.getUserRecords().addCallingInCityRecords(callRecord); 142 else if(callRecord.getCallingAddressAreaCode().matches("0790|079[2-9]|0701")) 143 u.getUserRecords().addCallingInProvinceRecords(callRecord); 144 else 145 u.getUserRecords().addCallingInLandRecords(callRecord); 146 } 147 } 148 if(u.getNumber().matches(callRecord.answerNumber)) { 149 if(callRecord.getStartTime().compareTo(callRecord.getEndTime())<=0) { 150 if(callRecord.getAnswerAddressAreaCode().matches("0791")) { 151 u.getUserRecords().addAnswerInCityRecords(callRecord); 152 } 153 else if(callRecord.getAnswerAddressAreaCode().matches("0790|079[2-9]|0701")) { 154 u.getUserRecords().addAnswerInProvinceRecords(callRecord); 155 } 156 else { 157 u.getUserRecords().addAnswerInLandRecords(callRecord); 158 } 159 } 160 } 161 } 162 } 163 public static void saveRecord(List<User> user,MessageRecord messageRecord) { //储存短信记录 164 165 for(User u:user) { 166 if(u.getNumber().matches(messageRecord.callingNumber)) { 167 u.getUserRecords().addSendMessageRecords(messageRecord); 168 } 169 if(u.getNumber().matches(messageRecord.answerNumber)) { 170 u.getUserRecords().addReceiveMessageRecords(messageRecord); 171 } 172 } 173 } 174 175 176 public static Date change(String s1,String s2) { //日期格式转换 177 SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); 178 String s = s1+" "+s2; 179 Date date = null; 180 try { 181 date = simpleDateFormat.parse(s); 182 } catch (ParseException e) { 183 e.printStackTrace(); 184 } 185 return date; 186 } 187 } 188 189 class SortByNum implements Comparator<Object>{ 190 191 @Override 192 public int compare(Object o1, Object o2) { 193 User s1 = (User) o1; 194 User s2 = (User) o2; 195 Long a1 = Long.parseLong(s1.getNumber()); 196 Long a2 = Long.parseLong(s2.getNumber()); 197 String m1 = a1.toString(); 198 String m2 = a2.toString(); 199 int result = 0; 200 201 if(m1.charAt(0)-m2.charAt(0)<0) { 202 return 1; 203 } 204 else if(m1.charAt(0)-m2.charAt(0)==0){ 205 for(int i = 1;i<m1.length() && i<m2.length();i++) { 206 result = m1.charAt(i)-m2.charAt(i); 207 if(result > 0) { 208 return 1; 209 } 210 } 211 } 212 return -1; 213 } 214 215 }
SourceMonitor报表:

第三题就是在前面的基础上写一个手机发短信付费的功能,不是很难,就根据之前的思路写就行了。但是对于短信的内容来计费又要求,超过十个字符则算一条短信,所以即使是一条短信发出去,计费也不是单按一条短信算,所以我通过do-while循环去判断单条短信到底能拆分成几条短信,代码如下:

然后剩下就是一些储存记录的代码了。
(4)农夫过河-界面版
核心代码:(界面代码)
1 package shiyan5; 2 3 import javafx.application.Application; 4 import javafx.event.ActionEvent; 5 import javafx.event.EventHandler; 6 import javafx.geometry.Insets; 7 import javafx.geometry.Pos; 8 import javafx.scene.Scene; 9 import javafx.scene.control.Button; 10 import javafx.scene.image.Image; 11 import javafx.scene.image.ImageView; 12 import javafx.scene.layout.GridPane; 13 import javafx.scene.layout.Pane; 14 import javafx.scene.paint.Color; 15 import javafx.scene.shape.Rectangle; 16 import javafx.stage.Stage; 17 18 public class Main extends Application { 19 GridPane pane = new GridPane(); 20 Game user = new Game(); 21 @Override 22 public void start(Stage stage) { 23 pane.setAlignment(Pos.CENTER); 24 pane.setPadding(new Insets(5,2,2,2)); 25 pane.setHgap(20); 26 pane.setVgap(20); 27 //加入图片效果 28 Image image = new Image("file:C:\\Users\\86137\\Pictures\\Saved Pictures\\图\\河.png"); 29 ImageView imageView = new ImageView(); 30 imageView.setImage(image); 31 imageView.setFitHeight(480); 32 imageView.setFitWidth(150); 33 pane.add(imageView,1,0,1,4); 34 35 Button[] bt = new Button[5]; 36 bt[1] = new Button("农夫独自过河"); 37 bt[2] = new Button("农夫带狼过河"); 38 bt[3] = new Button("农夫带羊过河"); 39 bt[4] = new Button("农夫带菜过河"); 40 bt[0] = new Button("退出游戏"); 41 bt[1].setMinSize(110,30); 42 bt[2].setMinSize(110,30); 43 bt[3].setMinSize(110,30); 44 bt[4].setMinSize(110,30); 45 bt[0].setMinSize(110,60); 46 ButtonEvents handle = new ButtonEvents(1); 47 bt[1].setOnAction(handle); 48 handle = new ButtonEvents(2); 49 bt[2].setOnAction(handle); 50 handle = new ButtonEvents(3); 51 bt[3].setOnAction(handle); 52 handle = new ButtonEvents(4); 53 bt[4].setOnAction(handle); 54 handle = new ButtonEvents(0); 55 bt[0].setOnAction(handle); 56 57 pane.add(bt[1],7,0 ); 58 pane.add(bt[2],7,1 ); 59 pane.add(bt[3],7,2 ); 60 pane.add(bt[4],7,3 ); 61 pane.add(bt[0],2,4 ); 62 63 Pane pane2 = new Pane(); 64 Rectangle rectangle; 65 rectangle = new Rectangle(500,500); 66 rectangle.setFill(Color.BEIGE); 67 68 Pane pane1 = new Pane(); 69 Pane pane3 = new Pane(); 70 71 Rectangle rectangle1,rectangle2; 72 rectangle1 = new Rectangle(500,0,130,600); 73 rectangle2 = new Rectangle(0,500,600,100); 74 rectangle1.setFill(Color.ANTIQUEWHITE); 75 rectangle2.setFill(Color.ANTIQUEWHITE); 76 pane1.getChildren().addAll(rectangle1); 77 pane3.getChildren().addAll(rectangle2); 78 pane2.getChildren().addAll(pane1); 79 pane2.getChildren().addAll(pane3); 80 81 pane2.getChildren().addAll(rectangle); 82 pane2.getChildren().addAll(pane);//将pane面板覆盖在pane2上 83 84 pane=user.play(pane,-1); 85 Scene scene = new Scene(pane2); 86 87 88 89 stage.setTitle("农夫过河"); 90 stage.setScene(scene); 91 stage.show(); 92 } 93 public static void main(String[] args) { 94 Application.launch(args); 95 } 96 class ButtonEvents implements EventHandler<ActionEvent> { 97 int flag; 98 ButtonEvents(int i) 99 { 100 this.flag=i; 101 } 102 @Override 103 public void handle(ActionEvent event) { 104 if(flag==0) 105 System.exit(0); 106 else 107 pane=user.play(pane,flag); 108 } 109 } 110 }
SourceMonitor报表:

类图:

写这题时,先是运用了多个抽象类,然后将书写各个子类,然后这个题关于对象的类时创建了一个物品类,里面包含了包菜、狼、羊和农夫。然后这几个对象都运用了单例模式,使得只创建一个对象。过河时首先需要判断农夫和船是否在一边,如果是要带物品过河的话还要判断物品和农夫是否在同一边。如果在的话过河之后需要判断河两侧的对象会不会存在被吃的情况。如果被吃的话则游戏结束,如果没有的话则继续游戏。
这个代码我觉得最好的地方在于,创建了一个游戏数据的类来专门存储游戏数据然后再通过生成游戏数据对象来调用其中数据,会比创建其他物品对象然后调用对象方便快捷。
然后将功能代码写好了之后,再往主函数中写界面的代码。我的农夫那些对象都是找的图片然后添加在面板上。然后设置了四个按钮,然后根据按钮选择对应的方法去实现功能。界面图如下:

但是这个代码不足的就是,因为是第一次用javafx写界面,我这个只能实现农夫一次带一个物品过河,不能实现自己设置船容量,然后同时带多个物品过河。
3.踩坑心德
写这次大作业的过程中,对于电信计费的号码排序一开始,是自己写了一个方法试图去排序,但是是没用的,然后我就以为是我的方法可能存在什么问题,虽然我知道Collections中是可以排序的,但是因为那个时候没用过那个,所以本着一种自己写比学习新东西时间化的更少的想法,就自己写了。然后自己写的方法没用,就还是去学习了用sort方法。然后包括一开始存储记录的时候有很多情况没存进去,比如用手机异地接听的扣费这个就没计算,然后导致结果错了。还有就是对日期的格式判断,当时觉得这个作业的测试点应该不回去考察闰年和二月的情况,就大概写了一个比较笼统的正则表达式上去判断,结果测试点确实是测试的很全面的。
写农夫过河时,因为是从实验二到实验五都在写这个问题,所以一开始的代码存在逻辑错误我也就将就写下去了,但是到了写后面实验的时候就会影响,然后又要去改,但是因为写第二次和上一次的代码时间间隔比较长,所有一旦代码的类分的多一点,就很容易忘记然后要重新了解代码再去修改。
4.改进建议
经过最近一次写酒店预约的界面,知道了怎么实现设置船容量然后带多个物品,只需要设置文本框,然后读取其中数据用于循环实现代码。之前之所以写不出来,是因为时间有点紧,所有导致只学习了一个比较简单的界面的建立和按钮,还有许多小组件没有学习,然后就开始写代码,而且也没又多的时间去修改完善功能。
5.总结
这几次实验对javafx的有了一定的了解,基本能使用其创建一个交互的界面,虽然对其中一些小组件的运用并不是那么那个,但是一些常见的比如按钮,标签和文本框还是可以熟练使用的。然后写完农夫过河之后也给我提供了一种新思路,就是之前总是通过创建许多对象去调用数据或者传递参数,但是现在可能再以后需要反复用到数据的时候可以考虑把他们的数据都传进个建好的数据类中,在通过数据对象去调用那些想要都想用的数据,这样不需要创建对象导致代码的冗长,而且调用数据的时候也很方便直观。
通过这段时间的学习,使得我明白了自己许多不足,而且因为提早放假的缘故,所有需要边复习其他科目准备考试,还需要边上课,然后还要分出时间去写java作业,确实是有点力不从心的,所有就导致后面几次作业都是赶出来的。而且再加上javafx这算是的上是一个新板块,所有写的时候需要边学边写,大大增加了时间成本,所有有关于界面的作业的完成情况都不是很好,但是也算得上是可以提交上去的作业。

浙公网安备 33010602011771号