Java第三次Blog
- 前言
- 这是我们在博客园上第三次写博客,也是本学期最后一次的JAVA学习大总结。现在我们的JAVA已经接近尾声了,对于编程思想和方法的改变依旧是难点,但是经过这一段时间的学习还是让我在OOP思想的理解上有了很大的进步,也学会了许多知识点,初步明白了不同语言之间的差别,不断的总结让我不停地思考自身的不足和缺陷,也让我不断的进步与努力,接下来便是对最后学习阶段的总结与认知。
1. 习题集六:
本次题目集一共包含两道题目,第一题是电信计费系统的设计,其中涉及到了正则表达式的运用,但是由于不够熟练,导致非法测试点好多无法实现,丢掉了十几分;第二题的难度更为简单一点,主要内容是定义容器Container接口,考察了对多态的测试,以及对接口的相关内容,主要难点为了接口的实现、抽象方法重写和多态机制测试,但做起来相对第一题来说容易一点。
2. 习题集七:
本次题目集一共包含了三道题目,第一题的难度在本次习题中难度最高,二,三题的难度相对而言难度一般。第一题难度较大,我得到的分很少,里面涉及到许多知识点还没有掌握,在csdn上学习过后仍然不是很明白,所以最后的分相当低,而第二题的考查范围主要是ArrayList和HashSet链表的使用,主要考察了对多个类的储存,再将其中的类进行数据对比,将重复的数据删除,考点为创建有序集合对象以及创建迭代器遍历集合。考点比较单一。第三题与第二题比较相似,考点也为考点为创建有序集合对象以及创建迭代器遍历集合。
3.习题集八
本次习题集一共有三道大题,难度相对于前两次的题目集有所降低,第三题是大致写一个动物发声模拟器,涉及到多态等问题,内容较为简单,第二题则是写一个shop类,可以用来巩固知识点,最难的还是第一题,但是相对前几次来说是简单的,经过询问多人后获得了满分。
- 习题集的得分情况:
习题集六:81分(满分100分)
习题集七:34分(满分100分)
习题集八:100分(满分100分)
- 设计与分析
下面为第一次的电信计费系统,其余均类似,故只对此进行讨论。
import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.Scanner; import javax.xml.crypto.Data; public class Main{ public static void main(String[] args) throws ParseException { Scanner in = new Scanner(System.in); ArrayList<User> u = new ArrayList<User>(); ArrayList<CallRecord> c = new ArrayList<CallRecord>(); String test = "^u-0791[0-9]{7,9} 0$"; String text1 = "[t]-0791[0-9]{7,8}\\s" + "0[0-9]{9,11}\\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 s = in.nextLine(); for(;!s.equals("end");) { if(s.charAt(0) == 'u') { if(s.matches(test)) { // if() { String[] a = s.split("[- ]"); User user = new User(a[1]); boolean falg = false; for(User user1 : u) { if(user1.getNumber().equals(a[1])) { falg = true; } } if(falg == false) { u.add(user); } // } } }else if(s.charAt(0) == 't') { if(s.matches(text1)) { SimpleDateFormat simpleFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); String[] b = s.split("[- ]"); String callnumberString = b[1]; String answernumberString =b[2]; String startTimeString = b[3] + " "+b[4]; String endTimeString = b[5] + " "+b[6]; Date st =simpleFormat.parse(startTimeString); Date et = simpleFormat.parse(endTimeString); CallRecord callRecord = new CallRecord(callnumberString,answernumberString); callRecord.setStartTime(st); callRecord.setEndTime(et); c.add(callRecord); } } s = in.nextLine(); } for(CallRecord callRecord : c) { String s1 = callRecord.getCallingNumber(); String s2 = callRecord.getAnswerNumber(); for(int i = 0; i < u.size(); i++){ if(u.get(i).getNumber().equals(s1)){ String num = s2.substring(0,4); if(num.equals("0791")){ u.get(i).getUserRecords().addCallinglnCityRecords(callRecord); }else if(num.equals("0701") || (num.compareTo("0790")>=0 && num.compareTo("0799")<=0)){ u.get(i).getUserRecords().addCallinglnProvinceRecords(callRecord); }else{ u.get(i).getUserRecords().addCallinglnLandRecords(callRecord); } } } } User[] u1 = u.toArray(new User[0]); for(int i = 0; i < u1.length-1; i++){ for(int j = i+1 ; j < u1.length;j++){ User temp; if(u1[i].getNumber().compareTo(u1[j].getNumber()) > 0){ temp = u1[i]; u1[i] = u1[j]; u1[j] = temp; } } } for(User user : u1){ System.out.printf("%s %.1f %.1f\n",user.getNumber(),user.calCost(),user.calBalance()); } } } class User{ private UserRecords userRecords = new UserRecords(); private double balance = 100; private double callcost = 0; private ChangeMode changeMode = new LandlinePhoneCharging(); private String number; public User(String number) { this.number = number; } public double calBalance() { balance = balance - changeMode.getMonthlyRent() - callcost; return balance; } public double calCost() { callcost = changeMode.calCost(userRecords); return callcost; } public UserRecords getUserRecords() { return userRecords; } public void setUserRecords(UserRecords userRecords) { this.userRecords = userRecords; } public ChangeMode getChargeMode() { return changeMode; } public void setChargeMode(ChangeMode changeMode) { this.changeMode = changeMode; } public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } } abstract class ChangeMode{ private ArrayList<ChargeRule> chargeRules = new ArrayList<>(); public ArrayList<ChargeRule> getChargeRules(){ return chargeRules; } public void setChargeRules(ArrayList<ChargeRule> chargeRules) { this.chargeRules = chargeRules; } public abstract double calCost(UserRecords userRecords) ; public abstract double getMonthlyRent() ; } class LandlinePhoneCharging extends ChangeMode{ private double monthlyRent = 20; CallChargeRule LandPhoneInCityRule = new LandPhoneInCityRule(); CallChargeRule LandPhonelnProvinceRule = new LandPhonelnProvinceRule(); CallChargeRule LandPhoneInLandRule = new LandPhoneInLandRule(); public double calCost(UserRecords userRecords) { double cost = 0; cost += LandPhoneInCityRule.calCost(userRecords.getCallinglnCityRecords()); cost += LandPhonelnProvinceRule.calCost(userRecords.getCallinglnProvinceRecords()); cost += LandPhoneInLandRule.calCost(userRecords.getCallinglnLandRecords()); return cost; } public double getMonthlyRent() { return monthlyRent; } } class UserRecords{ private ArrayList<CallRecord> callinglnCityRecords = new ArrayList<CallRecord>(); private ArrayList<CallRecord> callinglnProvinceRecords = new ArrayList<CallRecord>(); private ArrayList<CallRecord> callinglnLandRecords = new ArrayList<CallRecord>(); private ArrayList<CallRecord> answerlnCityRecords = new ArrayList<CallRecord>(); private ArrayList<CallRecord> answerlnProvinceRecords = new ArrayList<CallRecord>(); private ArrayList<CallRecord> answerlnLandceRecords = new ArrayList<CallRecord>(); private ArrayList<MessageRecord> sendMessageRecords = new ArrayList<MessageRecord>(); private ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<MessageRecord>(); public ArrayList<CallRecord> getCallinglnCityRecords(){ return callinglnCityRecords; } public ArrayList<CallRecord> getCallinglnProvinceRecords(){ return callinglnProvinceRecords; } public ArrayList<CallRecord> getCallinglnLandRecords(){ return callinglnLandRecords; } public ArrayList<CallRecord> getAnswerlnCityRecords(){ return answerlnCityRecords; } public ArrayList<CallRecord> getAnswerlnProvinceRecords(){ return answerlnProvinceRecords; } public ArrayList<CallRecord> getAnswerlnLandceRecords(){ return answerlnLandceRecords; } public ArrayList<MessageRecord> getSendMessageRecords(){ return sendMessageRecords; } public ArrayList<MessageRecord> getReceiveMessageRecords(){ return receiveMessageRecords; } public void addCallinglnCityRecords(CallRecord callRecord){ callinglnCityRecords.add(callRecord); } public void addCallinglnProvinceRecords(CallRecord callRecord){ callinglnProvinceRecords.add(callRecord); } public void addCallinglnLandRecords(CallRecord callRecord){ callinglnLandRecords.add(callRecord); } public void addAnswerlnCityRecords(CallRecord answerRecord){ answerlnCityRecords.add(answerRecord); } public void addAnswerlnProvinceRecords(CallRecord answerRecord){ answerlnProvinceRecords.add(answerRecord); } public void addAnswerlnLandceRecords(CallRecord answerRecord){ answerlnLandceRecords.add(answerRecord); } public void addSendMessageRecords(MessageRecord sendMessageRecords){ addSendMessageRecords(sendMessageRecords); } public void addReceiveMessageRecords(MessageRecord receiveMessageRecords){ addReceiveMessageRecords(receiveMessageRecords); } } abstract class CommunicationRecord{ protected String callingNumber; protected String answerNumber; public String getCallingNumber() { return callingNumber; } public void setCallingNumber(String callingNumber) { this.callingNumber = callingNumber; } public String getAnswerNumber() { return answerNumber; } public void setAnswerNumber(String answerNumber) { this.answerNumber = answerNumber; } } class CallRecord extends CommunicationRecord{ private Date startTime; private Date endTime; private String callingAddressAreaCode; private String answerAddressAreaCode; public CallRecord(String callnumberString, String answernumberString) { // TODO Auto-generated constructor stub setCallingNumber(callnumberString); setAnswerNumber(answernumberString); } public Date getStartTime() { return startTime; } public void setStartTime(Date startTime) { this.startTime = startTime; } public Date getEndTime() { return endTime; } public void setEndTime(Date endTime) { this.endTime = endTime; } public String getCallingAddressAreaCode() { return callingAddressAreaCode; } public void setCallingAddressAreaCode(String callingAddressAreaCode) { this.callingAddressAreaCode = callingAddressAreaCode; } public String getAnswerAddressAreaCode() { return answerAddressAreaCode; } public void setAnswerAddressAreaCode(String answerAddressAreaCode) { this.answerAddressAreaCode = answerAddressAreaCode; } } class MessageRecord extends CommunicationRecord{ private String message; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } } abstract class ChargeRule{ public ChargeRule() { super(); // TODO Auto-generated constructor stub } } abstract class CallChargeRule extends ChargeRule{ // SimpleDateFormat simpleFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); public abstract double calCost(ArrayList<CallRecord> callRecords) ; } class LandPhoneInCityRule extends CallChargeRule{ int minutes; int minute; int s; public double calCost(ArrayList<CallRecord> c) { for(CallRecord callRecord : c) { s = (int)(callRecord.getEndTime().getTime() - callRecord.getStartTime().getTime())/(1000); minute = (int)(s/60.0); if(s/60.0>minute) { minute++; } minutes+=minute; } return minutes*0.1; } } class LandPhoneInLandRule extends CallChargeRule{ int minutes; int minute; int s; public double calCost(ArrayList<CallRecord> c) { for(CallRecord callRecord : c) { s = (int)(callRecord.getEndTime().getTime() - callRecord.getStartTime().getTime())/(1000); minute = (int)(s/60.0); if(s/60.0>minute) { minute++; } minutes+=minute; } return minutes*0.6; } } class LandPhonelnProvinceRule extends CallChargeRule{ int minutes; int minute; int s; public double calCost(ArrayList<CallRecord> c) { for(CallRecord callRecord : c) { s = (int)(callRecord.getEndTime().getTime() - callRecord.getStartTime().getTime())/(1000); minute = (int)(s/60.0); if(s/60.0>minute) { minute++; } minutes+=minute; } return minutes*0.3; } }
下面的是省内计费的部分代码,其中对时间的换算很重要,经查询学会了date类的简单运用,
Date 类表示系统特定的时间戳,可以精确到毫秒。Date 对象表示时间的默认顺序是星期、月、日、小时、分、秒、年。
class LandPhonelnProvinceRule extends CallChargeRule{ int minutes; int minute; int s; public double calCost(ArrayList<CallRecord> c) { for(CallRecord callRecord : c) { s = (int)(callRecord.getEndTime().getTime() - callRecord.getStartTime().getTime())/(1000); minute = (int)(s/60.0); if(s/60.0>minute) { minute++; } minutes+=minute; } return minutes*0.3; } }
import java.awt.geom.Area; import java.text.ParseException; import java.util.Scanner; import javax.swing.text.AbstractDocument.LeafElement; //定义容器Container接口。模拟实现一个容器类层次结构,并进行接口的实现、抽象方法重写和多态机制测试。 //各容器类实现求表面积、体积的方法。 // //定义接口Container: //属性: //public static final double pi=3.1415926; //抽象方法: //其中两个静态方法分别计算返回容器数组中所有对象的面积之和、周长之和; //定义Cube类、Cylinder类均实现自Container接口。 //Cube类(属性:边长double类型)、Cylinder类(属性:底圆半径、高,double类型)。 public class Main{ public static void main(String[] args) throws ParseException { Scanner in = new Scanner(System.in); int n = in.nextInt(); Container[] containers = new Container[n]; for(int i = 0 ; i < n ; i++) { String a = in.next(); if(a.equals("cube")){ containers[i] = new Cube(in.nextDouble()); }else if(a.equals("cylinder")) { containers[i] = new Cylinder(in.nextDouble(), in.nextDouble()); } } System.out.printf("%.2f\n%.2f",Container.sumofArea(containers),Container.sumofVolume(containers)); in.close(); } } interface Container{ public abstract double area(); public abstract double volume(); public static double sumofArea(Container c[]) { double sum = 0; for(int i = 0;i < c.length;i++) { sum += c[i].area(); } return sum; } public static double sumofVolume(Container c[]) { double num = 0; for (Container container : c) { num += container.volume(); } return num; } } class Cube implements Container{ private double length; public Cube(double length) { this.length = length; } public double area() { return length*length*6; } public double volume() { return length*length*length; } } class Cylinder implements Container{ private double r; private double high; public static final double pi=3.1415926; public Cylinder(double r,double high) { this.r = r; this.high = high; } public double area() { return pi*r*r*2 + 2*r*pi*high; } public double volume() { return pi*r*r*high; } }
本题考查多态的类型,在期末考试时出现问题,PI要用Math.PI,没有用导致第一题都没有满分,除非题目有要求,否则一律使用Math.PI。
import java.util.Scanner; public class Main { public static void main(String[] args) { Shop myShop = new Shop(); Scanner inScanner = new Scanner(System.in); int num = inScanner.nextInt(); if(num >= 3) { myShop.setMilkCount(num); myShop.innerCoupons50.buy(); System.out.println("使用了面值为50的购物券进行支付"); System.out.println("牛奶还剩"+myShop.getMilkCount() +"箱"); myShop.innerCoupons100.buy(); System.out.println("使用了面值为100的购物券进行支付"); System.out.println("牛奶还剩"+ myShop.getMilkCount() +"箱"); } inScanner.close(); } } class Shop{ private int milkCount; InnerCoupons innerCoupons50; InnerCoupons innerCoupons100; public void setMilkCount(int milkCount) { this.milkCount = milkCount; } public int getMilkCount() { return milkCount; } public Shop() { innerCoupons50 = new InnerCoupons(50); innerCoupons100 = new InnerCoupons(100); } class InnerCoupons{ int value; public InnerCoupons(int value) { this.value = value; } public int getValue() { return value; } public void buy() { milkCount -= this.value/50; } } }
- 踩坑心得
①正则表达式默认进行贪婪匹配,可以用?来实现非贪婪匹配;
②字符串的直接比较可以采用equals连接前后两者,没必要依次比较每一个字符;
③Find函数用来对原始数据中某个字符串进行定位,以确定其位置,可以简化程序代码,使程序更加简洁明了;
④要善于用Java中一些功能方便的类,这样可以大大的提高我们的解题效率。
⑤在进行代码的编写时应该尽量避免代码的重复编写,使我的代码更加的简洁.
- 改进建议
①代码尽可能融入新的知识,一个功能一个类,避免一个类复用,导致代码的容错率降低,后期应逐步加入继承等新知识。
②顺序结构不够简洁,逻辑较为混乱,应在设计代码时提前用流程图进行规划,使程序清晰易读。
③不断考虑可能会出现的情况,不仅仅局限于测试点的通过。
④正则表达式的学习还不到位,仍然需要继续在网上查找资料来学习。
⑤在一些代码的关键节点,我应该加上一些注释,方便之后的查阅和修改。
⑥在进行继承关系描述时,需要注意格式问题,用super关键字来调用父类中的方法。
- 总结
①深入了解了正则表达式后学会了简单运用正则表达式。
②理解了面向对象程序设计封装性、继承性与多态性三大技术特性。
③理解面向过程程序设计和面向对象程序设计的区别。
④学习之路任重而道远,仍然需要努力,多向他人请教,问老师。