前言
本次是第三次Blog,也是这学期最后一个Bolg,这次主要分析的是电信计费系列的所有题目,可谓是一次非常真实的面向对象的编程,题目贴近生活,和我们息息相关,主要运用到的新知识包括正则表达式判断号码、地址、开户等,集合框架,用于存储数据的容器,集合框架是为表示和操作集合而规定的一种统一的标准的体系结构。任何集合框架都包含三大块内容:对外的接口、接口的实现和对集合运算的算法,SimpleDateFormat类的运用,在Java中,java.util包中的Date类可以获取当前时间,但是显示结果的时间格式不是很友好。而java.text包中的SimpleDateFormat类可以对日期时间进行格式转化,可以将日期转换成指定格式的文本,也可以将文本转换成日期。还有抽象类的使用,抽象类是指在普通类的结构里面增加抽象方法的组成部分。在所有的普通方法上面都会有一个“{}”,这个表示方法体,有方法体的方法一定可以被对象直接使用。而抽象方法,是指没有方法体的方法,同时抽象方法还必须使用关键字abstract做修饰。而拥有抽象方法的类就是抽象类,抽象类要使用abstract关键字声明。
总之,本次习题集让我们了解了使用所学知识去执行功能开发和使用,并站在对象的角度来思考问题,不断地完善和开发功能,尤其是对集合框架,我们要完全掌握,数据是程序的根本,我们需要存储数据,同时也需要对数据进行增、改、删、查。
设计与分析
7-1 电信计费系列1-座机计费 实现一个简单的电信计费程序:假设南昌市电信分公司针对市内座机用户采用的计费方式:月租20元,接电话免费,市内拨打电话0.1元/分钟,省内长途0.3元/分钟,国内长途拨打0.6元/分钟。不足一分钟按一分钟计。南昌市的区号:0791,江西省内各地市区号包括:0790~0799以及0701。
首先根据类图把框架给写出来,可以观察到,用户类的属性包括电话号码、余额、收费方式和用户记录,在用户记录类中包含了多种的打电话、接电话、发短信、接短信等记录用ArraryList容器来存储,通话记录类和短信记录类都继承CommunicationRecord抽象类,继承拨打电话、接听电话属性,在通话记录中有通话记录的开始和结束时间的属性,同时也有拨打电话地址和接听电话地址的属性,短信记录中只有短信内容的属性,CallChargRule抽象类中的抽象方法calCost()是用来计算打电话费用的计费方式,在LandPhoneInCityRule、LandPhoneInLandRule和LandPhoneInProinceRule子类中需重写这种方法,因为根据通话地址的不同,相对应产生的费用自然也不相同。
在构造完框架后,就可以开始存储数据了,首先要对数据的输入进行一个判断,这时就要用到正则表达式了,先创建一个String对象的ArraryList容器存储输入的数据,然后遍历容器,判断数据是开户还是通话记录,String strU1 = “u-0791//d{7,8}//s0”;//座机,用来匹配开户信息,
String strT1 = "(([t]-0791[0-9]{7,8}//s)|(t-1//d{10}//s0(//d{2,3})//s))" + "((0[0-9]{9,11}//s)|(1//d{10}//s0(//d{2,3})//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]))|(([469]|11)//.([1-9]|[12][0-9]|30))|(2//.([1-9]|[1][0-9]|2[0-8]))))|(((" + "[0-9]{2})([48]|[2468][048]|[13579][26])|(([48]|[2468][048]|[3579][26])00))//.2//.29))" + "//s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])//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})//.((([13578]|1[02])//.(" + "[1-9]|[12][0-9]|3[01]))|(([469]|11)//.([1-9]|[12][0-9]|30))|(2//.([1-9]|[1][0-9]|2[0-8]))))|(((" + "[0-9]{2})([48]|[2468][048]|[13579][26])|(([48]|[2468][048]|[3579][26])00))//.2//.29))" + "//s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])";
这条用来匹配通话记录信息,同样存入各自的容器,下一步就删去重复开户的记录,然后存入通话记录,用两个for循环,当通话记录的拨打电话和用户的号码一致时就存入到用户的用户记录中,对String数据的处理中我们要用到spilt方法,substring方法,完成之后再把这些通话记录存入相应的通话类型中,在Collections.sort()排序后,最后按顺序输出所有用户的消费情况。
7-1 电信计费系列2-手机+座机计费
实现南昌市电信分公司的计费程序,假设该公司针对手机和座机用户分别采取了两种计费方案,分别如下:
1、针对市内座机用户采用的计费方式(与电信计费系列1内容相同):
月租20元,接电话免费,市内拨打电话0.1元/分钟,省内长途0.3元/分钟,国内长途拨打0.6元/分钟。不足一分钟按一分钟计。
假设本市的区号:0791,江西省内各地市区号包括:0790~0799以及0701。
2、针对手机用户采用实时计费方式:
月租15元,市内省内接电话均免费,市内拨打市内电话0.1元/分钟,市内拨打省内电话0.2元/分钟,市内拨打省外电话0.3元/分钟,省内漫游打电话0.3元/分钟,省外漫游接听0.3元/分钟,省外漫游拨打0.6元/分钟;
注:被叫电话属于市内、省内还是国内由被叫电话的接听地点区号决定,比如以下案例中,南昌市手机用户13307912264在区号为020的广州接听了电话,主叫号码应被计算为拨打了一个省外长途,同时,手机用户13307912264也要被计算省外接听漫游费:
u-13307912264 1
t-079186330022 13307912264 020 2022.1.3 10:00:25 2022.1.3 10:05:11
这次习题集添加了手机用户,并且在地址上有多种不同的收费情况,但是不慌,有了第一题的框架,我们只需要添加新的代码去作出修改就行,在存数据时就要加一个,
String strU2 = “u-1//d{10}//s1”;//手机来匹配手机的开户了,其他都是大同小异,最主要的还是对于通话记录的收费方式,我们需要比较两个地址,来判断此次通话的收费方式,话不多说,直接放代码。
import java.util.*; import java.text.ParseException; import java.text.SimpleDateFormat; public class Main { public static void main(String[] args) throws ParseException { Scanner in = new Scanner(System.in); ArrayList<User> user = new ArrayList<>(); ArrayList<String> users_u = new ArrayList<>(); ArrayList<String[]> users_t = new ArrayList<>(); ArrayList<CallRecord> callRecords = new ArrayList<>(); String strU1 = "u-0791//d{7,8}//s0";//座机 String strU2 = "u-1//d{10}//s1";//手机 String Land = "0//d{9,11}"; String Phone = "1//d{10}"; String strT1 = "(([t]-0791[0-9]{7,8}//s)|(t-1//d{10}//s0(//d{2,3})//s))" + "((0[0-9]{9,11}//s)|(1//d{10}//s0(//d{2,3})//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]))|(([469]|11)//.([1-9]|[12][0-9]|30))|(2//.([1-9]|[1][0-9]|2[0-8]))))|(((" + "[0-9]{2})([48]|[2468][048]|[13579][26])|(([48]|[2468][048]|[3579][26])00))//.2//.29))" + "//s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])//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})//.((([13578]|1[02])//.(" + "[1-9]|[12][0-9]|3[01]))|(([469]|11)//.([1-9]|[12][0-9]|30))|(2//.([1-9]|[1][0-9]|2[0-8]))))|(((" + "[0-9]{2})([48]|[2468][048]|[13579][26])|(([48]|[2468][048]|[3579][26])00))//.2//.29))" + "//s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])"; String str2 = "07((9[0-9])|01)";//江西省的区号 String strM = "m-1//d{10}//s1//d{10}//s[(?i)[a-z]//d,.//s]+";//短信 SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); //存入输入信息 String information = ""; while(!information.equals("end")){ information = in.nextLine(); if(information.matches(strU1) || information.matches(strU2)) users_u.add(information); else if(information.matches(strT1)) { users_t.add(information.split(" ")); } } //存入用户信息 for (int i = 0; i < users_u.size(); i++) { user.add(new User(users_u.get(i).split(" ")[0].substring(2))); } //去除重复 for (int i = 0; i < user.size(); i++) { for (int j = i + 1; j < user.size(); j++) { if (user.get(i).number.equals(user.get(j).number)) { user.remove(j); break; } } } //存入通话记录 for (int i = 0; i < users_t.size(); i++) { if(users_t.get(i)[0].substring(2).matches(Land)){ if(users_t.get(i)[1].matches(Land)) { Date startTime = sdf.parse(users_t.get(i)[2]+" "+users_t.get(i)[3]); Date endTime = sdf.parse(users_t.get(i)[4]+" "+users_t.get(i)[5]); callRecords.add(new CallRecord(users_t.get(i)[0].substring(2), users_t.get(i)[0].substring(2, 6), users_t.get(i)[1], users_t.get(i)[1].substring(0, 4), startTime, endTime)); } else if(users_t.get(i)[1].matches(Phone)){ Date startTime = sdf.parse(users_t.get(i)[3]+" "+users_t.get(i)[4]); Date endTime = sdf.parse(users_t.get(i)[5]+" "+users_t.get(i)[6]); callRecords.add(new CallRecord(users_t.get(i)[0].substring(2), users_t.get(i)[0].substring(2, 6), users_t.get(i)[1], users_t.get(i)[2], startTime, endTime)); } } else if(users_t.get(i)[0].substring(2).matches(Phone)){ if(users_t.get(i)[2].matches(Phone)){ Date startTime = sdf.parse(users_t.get(i)[4]+" "+users_t.get(i)[5]); Date endTime = sdf.parse(users_t.get(i)[6]+" "+users_t.get(i)[7]); callRecords.add(new CallRecord(users_t.get(i)[0].substring(2), users_t.get(i)[1], users_t.get(i)[2], users_t.get(i)[3], startTime, endTime)); } else if(users_t.get(i)[2].matches(Land)){ Date startTime = sdf.parse(users_t.get(i)[3]+" "+users_t.get(i)[4]); Date endTime = sdf.parse(users_t.get(i)[5]+" "+users_t.get(i)[6]); callRecords.add(new CallRecord(users_t.get(i)[0].substring(2), users_t.get(i)[1], users_t.get(i)[2], users_t.get(i)[2].substring(0,4), startTime, endTime)); } } } //存入通话类型 for (int i = 0; i < callRecords.size(); i++) { for (int j = 0; j < user.size(); j++) { if(callRecords.get(i).callingNumber.equals(user.get(j).number)) { if (callRecords.get(i).answerAddressAreaCode.equals("0791")) { user.get(j).userRecords.callingInCityRecords.add(callRecords.get(i)); } else if (callRecords.get(i).answerAddressAreaCode.matches("(0790|0701|079[2~9])")) { user.get(j).userRecords.callingInProvinceRecords.add(callRecords.get(i)); } else user.get(j).userRecords.callingInLandRecords.add(callRecords.get(i)); } if(callRecords.get(i).answerNumber.equals(user.get(j).number)&&callRecords.get(i).answerNumber.matches(Phone)){ if(!callRecords.get(i).answerAddressAreaCode.matches(str2)){ user.get(j).userRecords.answerInLandRecords.add(callRecords.get(i)); } } } } //排序输出 Collections.sort(user); for (int i = 0; i < user.size(); i++) { if(user.get(i).number.matches(Land)) System.out.println(user.get(i).number + " " + String.format("%.1f", user.get(i).calCost()) + " " + String.format("%.1f", user.get(i).calBalance())); else if(user.get(i).number.matches(Phone)) System.out.println(user.get(i).number + " " + String.format("%.1f", user.get(i).calCost()) + " " + String.format("%.1f", user.get(i).calBalance1())); } } public static boolean isValidDate(String str) { boolean convertSuccess = true;// 指定日期格式为四位年/两位月份/两位日期,注意yyyy/MM/dd区分大小写; SimpleDateFormat format = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); try {// 设置lenient为false.否则SimpleDateFormat会比较宽松地验证日期,比如2007/02/29会被接受,并转换成2007/03/01 format.setLenient(false); format.parse(str); } catch (ParseException e) { // e.printStackTrace(); // 如果throw java.text.ParseException或者NullPointerException,就说明格式不对 convertSuccess = false; } return convertSuccess; } } class User implements Comparable<User> { double balance = 100; String number; UserRecords userRecords = new UserRecords(); ChargeMode chargeMode; public User(String number){ this.number = number; } public double calBalance(){ return balance-20-calCost(); } public double calBalance1(){ return balance-15-calCost(); } public double calCost(){ double Cost = 0; if(number.matches("0//d{9,11}")) { for (int i = 0; i < userRecords.callingInCityRecords.size(); i++) Cost += 0.1 * calTime(userRecords.callingInCityRecords.get(i).startTime, userRecords.callingInCityRecords.get(i).endTime); for (int i = 0; i < userRecords.callingInProvinceRecords.size(); i++) Cost += 0.3 * calTime(userRecords.callingInProvinceRecords.get(i).startTime, userRecords.callingInProvinceRecords.get(i).endTime); for (int i = 0; i < userRecords.callingInLandRecords.size(); i++) Cost += 0.6 * calTime(userRecords.callingInLandRecords.get(i).startTime, userRecords.callingInLandRecords.get(i).endTime); } if(number.matches("1//d{10}")) { for (int i = 0; i < userRecords.callingInCityRecords.size(); i++) { if(userRecords.callingInCityRecords.get(i).callingAddressAreaCode.equals("0791")) Cost += 0.1 * calTime(userRecords.callingInCityRecords.get(i).startTime, userRecords.callingInCityRecords.get(i).endTime); else if(userRecords.callingInCityRecords.get(i).callingAddressAreaCode.matches("(0790|0701|079[2~9])")) Cost += 0.3 * calTime(userRecords.callingInCityRecords.get(i).startTime, userRecords.callingInCityRecords.get(i).endTime); else Cost += 0.6 * calTime(userRecords.callingInCityRecords.get(i).startTime, userRecords.callingInCityRecords.get(i).endTime); } for (int i = 0; i < userRecords.callingInProvinceRecords.size(); i++) { if (userRecords.callingInProvinceRecords.get(i).callingAddressAreaCode.equals("0791")) Cost += 0.2 * calTime(userRecords.callingInProvinceRecords.get(i).startTime, userRecords.callingInProvinceRecords.get(i).endTime); else if(userRecords.callingInProvinceRecords.get(i).callingAddressAreaCode.matches("(0790|0701|079[2~9])")) Cost += 0.3 * calTime(userRecords.callingInProvinceRecords.get(i).startTime, userRecords.callingInProvinceRecords.get(i).endTime); else Cost += 0.6 * calTime(userRecords.callingInProvinceRecords.get(i).startTime, userRecords.callingInProvinceRecords.get(i).endTime); } for (int i = 0; i < userRecords.callingInLandRecords.size(); i++) { if (userRecords.callingInLandRecords.get(i).callingAddressAreaCode.equals("0791")) Cost += 0.3 * calTime(userRecords.callingInLandRecords.get(i).startTime, userRecords.callingInLandRecords.get(i).endTime); else if(userRecords.callingInLandRecords.get(i).callingAddressAreaCode.matches("(0790|0701|079[2~9])")) Cost += 0.3 * calTime(userRecords.callingInLandRecords.get(i).startTime, userRecords.callingInLandRecords.get(i).endTime); else Cost += 0.6 * calTime(userRecords.callingInLandRecords.get(i).startTime, userRecords.callingInLandRecords.get(i).endTime); } for (int i = 0; i < userRecords.answerInLandRecords.size(); i++) { Cost += 0.3 * calTime(userRecords.answerInLandRecords.get(i).startTime, userRecords.answerInLandRecords.get(i).endTime); } } return Cost; } public double calTime(Date startTime,Date endTime){ long diff = endTime.getTime() - startTime.getTime(); long diffSeconds = diff / 1000 % 60; long diffMinutes = diff / (60 * 1000) % 60; long diffHours = diff / (60 * 60 * 1000) % 24; long diffDays = diff / (24 * 60 * 60 * 1000); diffMinutes = diffMinutes+diffHours*60+diffDays*60*24; if(diffSeconds > 0) diffMinutes++; return diffMinutes; } @Override public int compareTo(User o) { return this.number.compareTo(o.number); } public double getBalance() { return balance; } public void setChargeMode(ChargeMode chargeMode) { this.chargeMode = chargeMode; } public UserRecords getUserRecords(){ return this.userRecords; } public ChargeMode getChargeMode() { return chargeMode; } public void setChargMode(ChargeMode chargeMode){ this.chargeMode = chargeMode; } public void setNumber(String number) { this.number = number; } public String getNumber() { return number; } } class UserRecords { ArrayList<CallRecord> callingInCityRecords = new ArrayList<>(); ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<>(); ArrayList<CallRecord> callingInLandRecords = new ArrayList<>(); ArrayList<CallRecord> answerInCityRecords = new ArrayList<>(); ArrayList<CallRecord> answerInProvinceRecords = new ArrayList<>(); ArrayList<CallRecord> answerInLandRecords = new ArrayList<>(); ArrayList<MessageRecord> sendMessageRecords = new ArrayList<>(); ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<>(); public ArrayList<CallRecord> getAnswerInCityRecords() { return answerInCityRecords; } public ArrayList<CallRecord> getAnswerInLandRecords() { return answerInLandRecords; } public ArrayList<CallRecord> getAnswerInProvinceRecords() { return answerInProvinceRecords; } public ArrayList<CallRecord> getCallingInCityRecords() { return callingInCityRecords; } public ArrayList<CallRecord> getCallingInLandRecords() { return callingInLandRecords; } public ArrayList<CallRecord> getCallingInProvinceRecords() { return callingInProvinceRecords; } public ArrayList<MessageRecord> getReceiveMessageRecords() { return receiveMessageRecords; } public ArrayList<MessageRecord> getSendMessageRecords() { return sendMessageRecords; } public void addAnswerInCityRecords(ArrayList<CallRecord> answerInCityRecords) { this.answerInCityRecords = answerInCityRecords; } public void addAnswerInLandRecords(ArrayList<CallRecord> answerInLandRecords) { this.answerInLandRecords = answerInLandRecords; } public void addAnswerInProvinceRecords(ArrayList<CallRecord> answerInProvinceRecords) { this.answerInProvinceRecords = answerInProvinceRecords; } public void addCallingInCityRecords(ArrayList<CallRecord> callingInCityRecords) { this.callingInCityRecords = callingInCityRecords; } public void addCallingInLandRecords(ArrayList<CallRecord> callingInLandRecords) { this.callingInLandRecords = callingInLandRecords; } public void addCallingInProvinceRecords(ArrayList<CallRecord> callingInProvinceRecords) { this.callingInProvinceRecords = callingInProvinceRecords; } public void addReceiveMessageRecords(ArrayList<MessageRecord> receiveMessageRecords) { this.receiveMessageRecords = receiveMessageRecords; } public void addSendMessageRecords(ArrayList<MessageRecord> sendMessageRecords) { this.sendMessageRecords = sendMessageRecords; } } abstract class ChargeMode//收费方式 { ArrayList<ChargRule> chargRules = new ArrayList<>(); public void setChargRules(ArrayList<ChargRule> chargRules) { this.chargRules = chargRules; } public ArrayList<ChargRule> getChargRules(){ return this.chargRules; } abstract double calCost(UserRecords userRecords); abstract double getMonthlyRent(); } class LandlinePhoneCharging extends ChargeMode { double monthlyRent = 20; public double calCost(UserRecords userRecords){ return 0; } public double getMonthlyRent(){ return this.monthlyRent; } } abstract class CommunicationRecord { String callingNumber; String answerNumber; public String getAnswerNumber() { return answerNumber; } public String getCallingNumber() { return callingNumber; } public void setAnswerNumber(String answerNumber) { this.answerNumber = answerNumber; } public void setCallingNumber(String callingNumber) { this.callingNumber = callingNumber; } } class CallRecord extends CommunicationRecord { Date startTime; Date endTime; String callingAddressAreaCode; String answerAddressAreaCode; public CallRecord(String callingNumber,String callingAddressAreaCode,String answerNumber,String answerAddressAreaCode,Date startTime,Date endTime){ this.setCallingNumber(callingNumber); this.setAnswerNumber(answerNumber); this.callingAddressAreaCode = callingAddressAreaCode; this.answerAddressAreaCode = answerAddressAreaCode; this.startTime = startTime; this.endTime = endTime; } public Date getEndTime() { return endTime; } public Date getStartTime() { return startTime; } public String getAnswerAddressAreaCode() { return answerAddressAreaCode; } public String getCallingAddressAreaCode() { return callingAddressAreaCode; } public void setAnswerAddressAreaCode(String answerAddressAreaCode) { this.answerAddressAreaCode = answerAddressAreaCode; } public void setCallingAddressAreaCode(String callingAddressAreaCode) { this.callingAddressAreaCode = callingAddressAreaCode; } public void setEndTime(Date endTime) { this.endTime = endTime; } public void setStartTime(Date startTime) { this.startTime = startTime; } } class MessageRecord extends CommunicationRecord { String message; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } } abstract class ChargRule { } abstract class CallChargRule extends ChargRule { abstract double calCost(ArrayList<CallRecord> callRecords); } class LandPhoneInCityRule extends CallChargRule { public double calCost(ArrayList<CallRecord> callRecords){ return 0; } } class LandPhoneInLandRule extends CallChargRule { public double calCost(ArrayList<CallRecord> callRecords){ return 0; } } class LandPhoneInProvinceRule extends CallChargRule { public double calCost(ArrayList<CallRecord> callRecords){ return 0; } }
7-1 电信计费系列3-短信计费
实现一个简单的电信计费程序,针对手机的短信采用如下计费方式:
1、接收短信免费,发送短信0.1元/条,超过3条0.2元/条,超过5条0.3元/条。
2、如果一次发送短信的字符数量超过10个,按每10个字符一条短信进行计算。
本题是短信计费,相比较于前两题简单一些,不需要判断地址,拿满分的人也比较多,根据要求接短信免费,发短信0.1元/条,超过3条0.2元/条,超过5条0.3元/条。如果一次发送短信的字符数量超过10个,按每10个字符一条短信进行计算。因此在短信条数的判断下,我们要逐条短信去分析,可能在一条信息内就包含多条短信,最后在累加起来就是短信条数的总量。
import java.util.*; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); ArrayList<User> user = new ArrayList<>(); ArrayList<String> users_u = new ArrayList<>(); ArrayList<String> a = new ArrayList<>(); ArrayList<String[]> users_m = new ArrayList<>(); String strU1 = "u-0791//d{7,8}//s0";//座机 String strU2 = "u-1//d{10}//s3";//手机 String strM = "m-1//d{10}//s1//d{10}//s[(?i)[a-z]//d,.//s]+";//短信 //存入输入信息 String information = ""; while(!information.equals("end")){ information = in.nextLine(); if(information.matches(strU1) || information.matches(strU2)) users_u.add(information); else if(information.matches(strM)){ a.add(information); } } for (int i = 0; i < a.size(); i++) { String[] b = new String[3]; b[0] = a.get(i).substring(2,13); b[1] = a.get(i).substring(14,24); b[2] = a.get(i).substring(25,a.get(i).length()-1); users_m.add(b); } //存入用户信息 for (int i = 0; i < users_u.size(); i++) { user.add(new User(users_u.get(i).split(" ")[0].substring(2))); } //去除重复 for (int i = 0; i < user.size(); i++) { for (int j = i + 1; j < user.size(); j++) { if (user.get(i).number.equals(user.get(j).number)) { user.remove(j); break; } } } //存入短信记录 for (int i = 0; i < users_m.size(); i++) { for (int j = 0; j < user.size(); j++) { if(users_m.get(i)[0].equals(user.get(j).number)) user.get(j).userRecords.sendMessageRecords.add(new MessageRecord(users_m.get(i)[2])); } } //排序输出 Collections.sort(user); for (int i = 0; i < user.size(); i++) { System.out.println(user.get(i).number + " " + String.format("%.1f", user.get(i).calCost()) + " " + String.format("%.1f", user.get(i).calBalance2())); } } } class User implements Comparable<User> { double balance = 100; String number; UserRecords userRecords = new UserRecords(); ChargeMode chargeMode; public User(String number){ this.number = number; } public double calBalance2(){ return balance-calCost(); } public double calCost(){ double Cost = 0; int number = 0; for (int i = 0; i < userRecords.sendMessageRecords.size(); i++) { if(userRecords.sendMessageRecords.get(i).message.toCharArray().length%10 == 0) number += userRecords.sendMessageRecords.get(i).message.length()/10; else if(userRecords.sendMessageRecords.get(i).message.toCharArray().length%10 != 0) number += userRecords.sendMessageRecords.get(i).message.length()/10+1; } if(number <= 3){ Cost += 0.1*number; } if(number > 3 && number <= 5){ Cost += 0.3+0.2*(number-3); } if(number > 5){ Cost += 0.7+0.3*(number-5); } return Cost; } @Override public int compareTo(User o) { return this.number.compareTo(o.number); } public double getBalance() { return balance; } public void setChargeMode(ChargeMode chargeMode) { this.chargeMode = chargeMode; } public UserRecords getUserRecords(){ return this.userRecords; } public ChargeMode getChargeMode() { return chargeMode; } public void setChargMode(ChargeMode chargeMode){ this.chargeMode = chargeMode; } public void setNumber(String number) { this.number = number; } public String getNumber() { return number; } } class UserRecords { ArrayList<CallRecord> callingInCityRecords = new ArrayList<>(); ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<>(); ArrayList<CallRecord> callingInLandRecords = new ArrayList<>(); ArrayList<CallRecord> answerInCityRecords = new ArrayList<>(); ArrayList<CallRecord> answerInProvinceRecords = new ArrayList<>(); ArrayList<CallRecord> answerInLandRecords = new ArrayList<>(); ArrayList<MessageRecord> sendMessageRecords = new ArrayList<>(); ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<>(); public ArrayList<CallRecord> getAnswerInCityRecords() { return answerInCityRecords; } public ArrayList<CallRecord> getAnswerInLandRecords() { return answerInLandRecords; } public ArrayList<CallRecord> getAnswerInProvinceRecords() { return answerInProvinceRecords; } public ArrayList<CallRecord> getCallingInCityRecords() { return callingInCityRecords; } public ArrayList<CallRecord> getCallingInLandRecords() { return callingInLandRecords; } public ArrayList<CallRecord> getCallingInProvinceRecords() { return callingInProvinceRecords; } public ArrayList<MessageRecord> getReceiveMessageRecords() { return receiveMessageRecords; } public ArrayList<MessageRecord> getSendMessageRecords() { return sendMessageRecords; } public void addAnswerInCityRecords(ArrayList<CallRecord> answerInCityRecords) { this.answerInCityRecords = answerInCityRecords; } public void addAnswerInLandRecords(ArrayList<CallRecord> answerInLandRecords) { this.answerInLandRecords = answerInLandRecords; } public void addAnswerInProvinceRecords(ArrayList<CallRecord> answerInProvinceRecords) { this.answerInProvinceRecords = answerInProvinceRecords; } public void addCallingInCityRecords(ArrayList<CallRecord> callingInCityRecords) { this.callingInCityRecords = callingInCityRecords; } public void addCallingInLandRecords(ArrayList<CallRecord> callingInLandRecords) { this.callingInLandRecords = callingInLandRecords; } public void addCallingInProvinceRecords(ArrayList<CallRecord> callingInProvinceRecords) { this.callingInProvinceRecords = callingInProvinceRecords; } public void addReceiveMessageRecords(ArrayList<MessageRecord> receiveMessageRecords) { this.receiveMessageRecords = receiveMessageRecords; } public void addSendMessageRecords(ArrayList<MessageRecord> sendMessageRecords) { this.sendMessageRecords = sendMessageRecords; } } abstract class ChargeMode//收费方式 { ArrayList<ChargRule> chargRules = new ArrayList<>(); public void setChargRules(ArrayList<ChargRule> chargRules) { this.chargRules = chargRules; } public ArrayList<ChargRule> getChargRules(){ return this.chargRules; } abstract double calCost(UserRecords userRecords); abstract double getMonthlyRent(); } class LandlinePhoneCharging extends ChargeMode { double monthlyRent = 20; public double calCost(UserRecords userRecords){ return 0; } public double getMonthlyRent(){ return this.monthlyRent; } } abstract class CommunicationRecord { String callingNumber; String answerNumber; public String getAnswerNumber() { return answerNumber; } public String getCallingNumber() { return callingNumber; } public void setAnswerNumber(String answerNumber) { this.answerNumber = answerNumber; } public void setCallingNumber(String callingNumber) { this.callingNumber = callingNumber; } } class CallRecord extends CommunicationRecord { Date startTime; Date endTime; String callingAddressAreaCode; String answerAddressAreaCode; public CallRecord(String callingNumber,String callingAddressAreaCode,String answerNumber,String answerAddressAreaCode,Date startTime,Date endTime){ this.setCallingNumber(callingNumber); this.setAnswerNumber(answerNumber); this.callingAddressAreaCode = callingAddressAreaCode; this.answerAddressAreaCode = answerAddressAreaCode; this.startTime = startTime; this.endTime = endTime; } public Date getEndTime() { return endTime; } public Date getStartTime() { return startTime; } public String getAnswerAddressAreaCode() { return answerAddressAreaCode; } public String getCallingAddressAreaCode() { return callingAddressAreaCode; } public void setAnswerAddressAreaCode(String answerAddressAreaCode) { this.answerAddressAreaCode = answerAddressAreaCode; } public void setCallingAddressAreaCode(String callingAddressAreaCode) { this.callingAddressAreaCode = callingAddressAreaCode; } public void setEndTime(Date endTime) { this.endTime = endTime; } public void setStartTime(Date startTime) { this.startTime = startTime; } } class MessageRecord extends CommunicationRecord { String message; public MessageRecord(String message){ this.message = message; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } } abstract class ChargRule { } abstract class CallChargRule extends ChargRule { abstract double calCost(ArrayList<CallRecord> callRecords); } class LandPhoneInCityRule extends CallChargRule { public double calCost(ArrayList<CallRecord> callRecords){ return 0; } } class LandPhoneInLandRule extends CallChargRule { public double calCost(ArrayList<CallRecord> callRecords){ return 0; } } class LandPhoneInProvinceRule extends CallChargRule { public double calCost(ArrayList<CallRecord> callRecords){ return 0; } }
踩坑心得
在这三次习题集中,我多次运用到了正则表达式,很显然正则表达式是一个非常好的方法,但编写一个匹配字段也是有难度的,所以需要掌握正则表达式的编写规则和方法,同时对于字符串的处理也要更加熟练,例如spilt切割字符串为字符串数组,substring同样可以根据索引值来截取某段字符串,但是要知道索引值的位置,而且要对运用容器存储数据完全掌握,因为数据的类型、数量都可能会非常之多,Collections:集合工具类,方便对集合的操作。这个类不需要创建对象,内部提供的都是静态方法。如何选用集合?主要根据集合的特点来选用,比如我们需要根据键值获取到元素值时就选用Map接口下的集合,需要排序时选择TreeMap,不需要排序时就选择HashMap,需要保证线程安全就选用ConcurrentHashMap.当我们只需要存放元素值时,就选择实现Collection接口的集合,需要保证元素唯一时选择实现Set接口的集合比如TreeSet或HashSet,不需要就选择实现List接口的比如ArrayList或LinkedList,然后再根据实现这些接口的集合的特点来选用。
改进建议
减少圈复杂度,在网上查找的减少圈复杂度的方法,都可以减少我的代码圈复杂度,比如用switch代替if else ,减少判断。代码的设计应尽可能的具有单一职责性,一个功能一个类,功能越复杂的类的代码其复用性越差,越不利与我们对于代码的复用。减少代码与代码的耦合性,一个类应该对自己需要耦合或者调用的类知道的越少越好,遵循迪米特原则设计子类和父类,对于需要不断进行更改和使用的方法应该进行抽象化,用子类去继承他们,减少我们对于代码的修改,遵循开闭原则。在一些代码的关键节点,我应该加上一些注释,方便之后的查阅和修改。不断优化实现功能的代码算法,减少代码的圈复杂度。
总结
本学期的面向对象程序设计课程也快要结课了,对于JAVA这门语言,我认为有这几大特性:简单性、面向对象、分布式、健壮性、安全性、体系结构中立、可移植性、解释性、高性能、多线程、多态性。Java语言是C++语言的一个“纯净”版本。没有头文件、指针运算、结构、联合、操作符重载、虚基类等,面向对象即面向数据。Java的面向对象特性与C++旗鼓相当,Java与C++的主要不同点在于多继承,在Java中,取而代之的是更简单的接口概念多线程可以带来更好的交互响应和实时行为。如今大家非常关注并发性,我们不在追求更快的处理器,而是更多的处理器,Java是第一个支持并发的主流语言。在今后的学习中我要更加勤奋和努力,在程序设计方面多多下功夫,学习新的知识,巩固自己的基础。
原创文章,作者:Maggie-Hunter,如若转载,请注明出处:https://blog.ytso.com/268173.html