一.前言:

本次Blog是对之前发布的PTA题目集的总结性Blog,这几次的作业题量,难度都不大,但都趋近于完成一整个系统,而非只实现部分的功能。题目集九、十也不在给出类图,而是要求自己设计。我认为这是比较好的,不想当码农,而是要自己的设计能力。这几次作业主要是迭代,从题目集八到十的电信计费系列从座机到手机再到短信,如果第一次没有设计好在后面会很不轻松。还有其他几道练习题,比较简单。

二.设计与分析、

实现一个简单的电信计费程序:
假设南昌市电信分公司针对市内座机用户采用的计费方式:
月租20元,接电话免费,市内拨打电话0.1元/分钟,省内长途0.3元/分钟,国内长途拨打0.6元/分钟。不足一分钟按一分钟计。
南昌市的区号:0791,江西省内各地市区号包括:0790~0799以及0701。

输入格式:

输入信息包括两种类型
1、逐行输入南昌市用户开户的信息,每行一个用户,
格式:u-号码 计费类型 (计费类型包括:0-座机 1-手机实时计费 2-手机A套餐)
例如:u-079186300001 0
座机号码除区号外由是7-8位数字组成。
本题只考虑计费类型0-座机计费,电信系列2、3题会逐步增加计费类型。
2、逐行输入本月某些用户的通讯信息,通讯信息格式:
座机呼叫座机:t-主叫号码 接听号码 起始时间 结束时间
t-079186330022 058686330022 2022.1.3 10:00:25 2022.1.3 10:05:11
以上四项内容之间以一个英文空格分隔,
时间必须符合"yyyy.MM.dd HH:mm:ss"格式。提示:使用SimpleDateFormat类。
以上两类信息,先输入所有开户信息,再输入所有通讯信息,最后一行以“end”结束。
注意:
本题非法输入只做格式非法的判断,不做内容是否合理的判断(时间除外,否则无法计算),比如:
1、输入的所有通讯信息均认为是同一个月的通讯信息,不做日期是否在同一个月还是多个月的判定,直接将通讯费用累加,因此月租只计算一次。
2、记录中如果同一电话号码的多条通话记录时间出现重合,这种情况也不做判断,直接 计算每条记录的费用并累加。
3、用户区号不为南昌市的区号也作为正常用户处理。

输出格式:

根据输入的详细通讯信息,计算所有已开户的用户的当月费用(精确到小数点后2位,
单位元)。假设每个用户初始余额是100元。
每条通讯信息单独计费后累加,不是将所有时间累计后统一计费。
格式:号码+英文空格符+总的话费+英文空格符+余额
每个用户一行,用户之间按号码字符从小到大排序。

错误处理:
输入数据中出现的不符合格式要求的行一律忽略。

建议类图:
参见图1、2、3,可根据理解自行调整:

图1中User是用户类,包括属性:
userRecords (用户记录)、balance(余额)、chargeMode(计费方式)、number(号码)。 ChargeMode是计费方式的抽象类:
chargeRules是计费方式所包含的各种计费规则的集合,ChargeRule类的定义见图3。
getMonthlyRent()方法用于返回月租(monthlyRent)。 UserRecords是用户记录类,保存用户各种通话、短信的记录,
各种计费规则将使用其中的部分或者全部记录。
其属性从上到下依次是:
市内拨打电话、省内(不含市内)拨打电话、省外拨打电话、
市内接听电话、省内(不含市内)接听电话、省外接听电话的记录
以及发送短信、接收短信的记录。
 

图2中CommunicationRecord是抽象的通讯记录类:
包含callingNumber拨打号码、answerNumber接听号码两个属性。
CallRecord(通话记录)、MessageRecord(短信记录)是它的子类。 CallRecord(通话记录类)包含属性:
通话的起始、结束时间以及
拨号地点的区号(callingAddressAreaCode)、接听地点的区号(answerAddressAreaCode)。
区号用于记录在哪个地点拨打和接听的电话。座机无法移动,就是本机区号,如果是手机号,则会有差异。
 

图3是计费规则的相关类,这些类的核心方法是:
calCost(ArrayList<CallRecord> callRecords)。
该方法针根据输入参数callRecords中的所有记录计算某用户的某一项费用;如市话费。
输入参数callRecords的约束条件:必须是某一个用户的符合计费规则要求的所有记录。 LandPhoneInCityRule、LandPhoneInProvinceRule、LandPhoneInLandRule三个类分别是
座机拨打市内、省内、省外电话的计费规则类,用于实现这三种情况的费用计算。
(提示:可以从UserRecords类中获取各种类型的callRecords)。
 

后续扩展说明:
后续题目集将增加手机用户,手机用户的计费方式中除了与座机计费类似的主叫通话费之外,还包含市外接听电话的漫游费以及发短信的费用。在本题的设计时可统一考虑。
通话记录中,手机需要额外记录拨打/接听的地点的区号,比如:
座机打手机:t-主叫号码 接听号码 接听地点区号 起始时间 结束时间
t-079186330022 13305862264 020 2022.1.3 10:00:25 2022.1.3 10:05:11
手机互打:t-主叫号码 拨号地点 接听号码 接听地点区号 起始时间 结束时间
t-18907910010 0791 13305862264 0371 2022.1.3 10:00:25 2022.1.3 10:05:11
短信的格式:m-主叫号码,接收号码,短信内容
m-18907910010 13305862264 welcome to jiangxi
m-13305862264 18907910010 thank yo

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.Date;
public class Main {
public static void main(String[] args) throws ParseException{
SimpleDateFormat SimpleDateFormat=new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
ArrayList<User> Users=new ArrayList<User>();
Scanner sc=new Scanner(System.in);
String a=sc.nextLine();
int m=0;
while(true)
{
if(a.matches("[u]-0791[0-9]{7,8} 0"))
{
Users.add(new User());
int q=a.indexOf(' ');
Users.get(m).number=a.substring(2,q);
Users.get(m).chargeMode=new LandlinePhoneCharging();
}
m++;
a=sc.nextLine();
if(a.charAt(0)=='t')
break;
}
String c=a;
while(!c.equals("end"))
{
int n=0;
int l=Users.size();
if(c.matches("t-[\\d]{11,12}\\s[\\d]{11,12}\\s[\\d]{4}.[\\d]{1,2}.[\\d]{1,2}\\s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])\\s[\\d]{4}.[\\d]{1,2}.[\\d]{1,2}\\s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])"))
{
while(n<l)
{

try{
// 可能会导致错误的代码
int q=c.indexOf(' ');
if(Users.get(n).number.equals(c.substring(2,q)))
{

if(User.numaeral(c.substring(q+2,q+5))==0)
{

q=c.indexOf(' ',q+1);
int w=q;
q=c.indexOf(' ',q+1);
q=c.indexOf(' ',q+1);
if(check(c.substring(w+1, q))&&check(c.substring(q+1)))
{
Users.get(n).userRecords.callingInCityRecords.add(new CallRecord());
int le=Users.get(n).userRecords.callingInCityRecords.size();
Users.get(n).userRecords.callingInCityRecords.get(le-1).startTime=SimpleDateFormat.parse(c.substring(w+1, q));
Users.get(n).userRecords.callingInCityRecords.get(le-1).endTime=SimpleDateFormat.parse(c.substring(q+1));
}
}
else if(User.numaeral(c.substring(q+2,q+5))==1)
{

q=c.indexOf(' ',q+1);
int w=q;
q=c.indexOf(' ',q+1);
q=c.indexOf(' ',q+1);
if(check(c.substring(w+1, q))&&check(c.substring(q+1)))
{
Users.get(n).userRecords.callingInProvinceRecords.add(new CallRecord());
int le=Users.get(n).userRecords.callingInProvinceRecords.size();
Users.get(n).userRecords.callingInProvinceRecords.get(le-1).startTime=SimpleDateFormat.parse(c.substring(w+1, q));
Users.get(n).userRecords.callingInProvinceRecords.get(le-1).endTime=SimpleDateFormat.parse(c.substring(q+1));
}
}
else
{

q=c.indexOf(' ',q+1);
int w=q;
q=c.indexOf(' ',q+1);
q=c.indexOf(' ',q+1);
if(check(c.substring(w+1, q))&&check(c.substring(q+1)))
{
Users.get(n).userRecords.callingInLandRecords.add(new CallRecord());
int le=Users.get(n).userRecords.callingInLandRecords.size();
Users.get(n).userRecords.callingInLandRecords.get(le-1).startTime=SimpleDateFormat.parse(c.substring(w+1, q));
Users.get(n).userRecords.callingInLandRecords.get(le-1).endTime=SimpleDateFormat.parse(c.substring(q+1));
}
}
}
}
catch(Exception e){
// 在错误发生时怎么处理
}
n++;
}
}
c=sc.nextLine();
}
int y;
int j;
User t=new User();
for(y=0;y<Users.size();y++)
{
for(j=y+1;j<Users.size();j++)
{
if(Users.get(y).number.equals(Users.get(j).number))
{
Users.remove(j);
}
else if(Users.get(y).number.charAt(11)>Users.get(j).number.charAt(11))
{
t=Users.get(y);
Users.set(y, Users.get(j));
Users.set(j,t);
}

}
}
y=0;
while(y<Users.size())
{
System.out.printf("%s %.1f %.1f",Users.get(y).number,Users.get(y).calCost(),(80-Users.get(y).calCost()));
System.out.printf("\n");
y++;
}
}
static boolean check (String str) {
SimpleDateFormat sd=new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");//括号内为日期格式,y代表年份,M代表年份中的月份(为避免与小时中的分钟数m冲突,此处用M),d代表月份中的天数
try {
sd.setLenient(false);//此处指定日期/时间解析是否不严格,在true是不严格,false时为严格
sd.parse(str);//从给定字符串的开始解析文本,以生成一个日期
}
catch (Exception e) {
return false;
}
return true;
}
}
abstract class CallChargeRule extends ChargeRule {
SimpleDateFormat SimpleDateFormat=new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
public abstract double calCost (UserRecords userRecords);
}
class CallRecord extends CommunicationRecord{
Date startTime;
Date endTime;
String callingAddressAreaCode;
String answerAddressAreaCode;
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;
}
}
abstract class chargeMode {
ArrayList<ChargeRule> chargeRules = new ArrayList<>();
public abstract double calCost (UserRecords userRecords);
public abstract double getMonthlyRent ();
public ArrayList<ChargeRule> getChargeRules() {
return chargeRules;
}
public void setChargeRules(ArrayList<ChargeRule> chargeRules) {
this.chargeRules = chargeRules;
}
}
abstract class ChargeRule {
public abstract double calCost (UserRecords userRecords);
}
abstract class CommunicationRecord {
String callingNumber;
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 LandlinePhoneCharging extends chargeMode {

@Override
public double calCost(UserRecords userRecords) {
chargeRules.add(new LandPhoneInCityRule());
chargeRules.add(new LandPhoneInProvinceRule());
chargeRules.add(new LandPhoneInlandRule());
return chargeRules.get(0).calCost(userRecords)+chargeRules.get(1).calCost(userRecords)+chargeRules.get(2).calCost(userRecords);
}

@Override
public double getMonthlyRent() {
// TODO Auto-generated method stub
return 20;
}

}
class LandPhoneInCityRule extends CallChargeRule {
@Override
public double calCost(UserRecords userRecords) {
int i=0;
double s=0;
double m=0;
while(i<userRecords.callingInCityRecords.size())
{
try {
long time1=userRecords.callingInCityRecords.get(i).startTime.getTime();
long time2=userRecords.callingInCityRecords.get(i).endTime.getTime();
long time=(time2-time1);
i++;
s=(double)time;
m=Math.ceil(s/1000/60)*0.1+m;
}
catch(Exception e){
i++;
}
}
if(m>=0)
return m;
else
{
return 0;
}
}
}
class LandPhoneInlandRule extends CallChargeRule {

@Override
public double calCost(UserRecords userRecords) {
int i=0;
double s=0;
double m=0;
while(i<userRecords.callingInLandRecords.size())
{
try {
long time1=userRecords.callingInLandRecords.get(i).startTime.getTime();
long time2=userRecords.callingInLandRecords.get(i).endTime.getTime();
long time=(time2-time1);
i++;
s=(double)time;
m=m+Math.ceil(s/1000/60)*0.6;
}
catch(Exception e){
i++;
}
}
if(m>=0)
return m;
else
{
return 0;
}
}
}

class LandPhoneInProvinceRule extends CallChargeRule {

@Override
public double calCost(UserRecords userRecords) {
int i=0;
double s=0;
double m=0;
while(i<userRecords.callingInProvinceRecords.size())
{
try {
long time1=userRecords.callingInProvinceRecords.get(i).startTime.getTime();
long time2=userRecords.callingInProvinceRecords.get(i).endTime.getTime();
long time=(time2-time1);
i++;
s=(double)time;
m=Math.ceil(s/1000/60)*0.3+m;
}
catch(Exception e){
i++;
}
}
if(m>=0)
return m;
else
{
return 0;
}
}

}
class MessageRecord extends CommunicationRecord{
String message;

public String getMessage() {
return message;
}

public void setMessage(String message) {
this.message = message;
}
}
class User {
UserRecords userRecords =new UserRecords();
double balance=100;
chargeMode chargeMode;
String number;
public UserRecords getUserRecords() {
return userRecords;
}
public void setUserRecords(UserRecords userRecords) {
this.userRecords = userRecords;
}
public double getBalance() {
return balance;
}
public chargeMode getChargeMode() {
return chargeMode;
}
public void setChargeMode(chargeMode chargeMode) {
this.chargeMode = chargeMode;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public double calBalance () {
return balance;
}
public double calCost () {
return chargeMode.calCost(userRecords);
}
public static int numaeral(String number) {
if(Integer.parseInt(number)==791)
return 0;
else if(Integer.parseInt(number)>=790&&Integer.parseInt(number)<799||Integer.parseInt(number)==701)
return 1;
else
return 2;
}
}
class UserRecords {
ArrayList<CallRecord> callingInCityRecords=new ArrayList<CallRecord>();
ArrayList<CallRecord> callingInProvinceRecords =new ArrayList<CallRecord>();
ArrayList<CallRecord> callingInLandRecords=new ArrayList<CallRecord>();
ArrayList<CallRecord> answerInCityRecords=new ArrayList<CallRecord>();
ArrayList<CallRecord> answerInProvinceRecords=new ArrayList<CallRecord>();
ArrayList<CallRecord> answerInLandRecords=new ArrayList<CallRecord>();
ArrayList<MessageRecord> sendMessageRecords=new ArrayList<MessageRecord>();
ArrayList<MessageRecord> receiveMessageRecords=new ArrayList<MessageRecord>();
public ArrayList<CallRecord> getCallingInCityRecords() {
return callingInCityRecords;
}
public void addCallingInCityRecords (CallRecord callRecord)
{
callingInCityRecords.add(callRecord);
}
public ArrayList<CallRecord> getCallingInProvinceRecords() {
return callingInProvinceRecords;
}
public void addCallingInProvinceRecords (CallRecord callRecord)
{
callingInProvinceRecords .add(callRecord);
}

public ArrayList<CallRecord> getCallingInLandRecords() {
return callingInLandRecords;
}
public void addCallingInLandRecords (CallRecord callRecord)
{
callingInLandRecords.add(callRecord);
}
public ArrayList<CallRecord> getAnswerInCityRecords() {
return answerInCityRecords;
}
public void addAnswerInCityRecords (CallRecord answerRecord)
{
answerInCityRecords.add(answerRecord);
}
public ArrayList<CallRecord> getAnswerInProvinceRecords() {
return answerInProvinceRecords;
}
public void addAnswerInProvinceRecords (CallRecord answerRecord)
{
answerInProvinceRecords.add(answerRecord);
}
public ArrayList<CallRecord> getAnswerInLandRecords() {
return answerInLandRecords;
}
public void addAnswerInLandRecords (CallRecord answerRecord)
{
answerInLandRecords.add(answerRecord);
}
public ArrayList<MessageRecord> getSendMessageRecords() {
return sendMessageRecords;
}
public void addSendMessageRecords (MessageRecord sendMessageRecord)
{
sendMessageRecords.add(sendMessageRecord);
}
public ArrayList<MessageRecord> getReceiveMessageRecords() {
return receiveMessageRecords;
}
public void addReceiveMessageRecords (MessageRecord receiveMessageRecord)
{
receiveMessageRecords.add(receiveMessageRecord);
这个题主要是做座机的收费较为局限性,只考虑座机的情况且只考虑打电话的情况。主要运用的ArrayList的使用,以及考察类的设计,但是给了类的设计图,把难度减少了许多。

实现南昌市电信分公司的计费程序,假设该公司针对手机和座机用户分别采取了两种计费方案,分别如下:
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也要被计算省外接听漫游费:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.Scanner;

public class Main {

public static void main(String[] args) {
Scanner in = new Scanner(System.in);
ArrayList<User> users1 = new ArrayList<User>();
ArrayList<User> users2 = new ArrayList<User>();
ChargeMode chargeMode;
ArrayList<CallRecord> callRecords = new ArrayList<CallRecord>();
SimpleDateFormat df = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");

String[] tokens = null;
Date time1=null,time2=null;
while(true)
{
String number=in.nextLine();
if(number.equals("end"))
break;
int f=0;
f=JudgeFormat.judge(number);
if(f!=0)
{
for(int i=0;i<number.length();i++)
{
tokens=number.split("[- ]");
}

if(tokens[0].equals("u")){//开户
CallRecord callRecord = new CallRecord();
String areaCode;
LandlinePhoneCharging m = new LandlinePhoneCharging();//座机
MobilePhoneCharging n =new MobilePhoneCharging();//手机
chargeMode = m;
chargeMode = n;
if(f==1)
{
boolean judge=true;
areaCode = tokens[1].substring(0, 4);
callRecord.setCallingAddressAreaCode(areaCode);//区号
for(User user : users1)
{
if(user.getNumber().equals(tokens[1]))//判断是否已开户
judge=false;
}
if(judge) {//如果没有就开户
User u = new User(m,tokens[1]);
users1.add(u);//开户
}
}
else if(f==2)
{
boolean judge=true;
for(User user : users2)
{
if(user.getNumber().equals(tokens[1]))//判断是否已开户
judge=false;
}
if(judge) {//如果没有就开户
User u = new User(n,tokens[1]);
users2.add(u);//开户
}
}
}

if(tokens[0].equals("t")) {
CallRecord callRecord = new CallRecord();
String anwserareaCode,callareaCode;
if(f==3)
{
callareaCode = tokens[1].substring(0, 4);//拨打区号
callRecord.setCallingAddressAreaCode(callareaCode);//传入拨打区号
callRecord.setCallingNumber(tokens[1]);//传入拨打号码
anwserareaCode = tokens[2].substring(0, 4);//接通地址
callRecord.setAnswerAddressAreaCode(anwserareaCode);//传入接通区号
callRecord.setAnswerNumber(tokens[2]);//传入接通号码
try {
time1 = df.parse(tokens[3]+" "+tokens[4]);
} catch (ParseException e1) {
e1.printStackTrace();
}

try {
time2 = df.parse(tokens[5]+" "+tokens[6]);
} catch (ParseException e) {
e.printStackTrace();
}

callRecord.setStartTime(time1);//开始时间
callRecord.setEndTime(time2);//结束时间
callRecords.add(callRecord);//添加用户记录
}

if(f==4)
{
callareaCode = tokens[1].substring(0, 4);//拨打区号
callRecord.setCallingAddressAreaCode(callareaCode);//传入拨打区号
callRecord.setCallingNumber(tokens[1]);//传入拨打号码
anwserareaCode = tokens[3];//接通地址
callRecord.setAnswerAddressAreaCode(anwserareaCode);//传入接通区号
callRecord.setAnswerNumber(tokens[2]);//传入接通号码
try {
time1 = df.parse(tokens[4]+" "+tokens[5]);
} catch (ParseException e1) {
e1.printStackTrace();
}

try {
time2 = df.parse(tokens[6]+" "+tokens[7]);
} catch (ParseException e) {
e.printStackTrace();
}

callRecord.setStartTime(time1);//开始时间
callRecord.setEndTime(time2);//结束时间
callRecords.add(callRecord);//添加用户记录
}

if(f==5)
{
callareaCode = tokens[2];//拨打区号
callRecord.setCallingAddressAreaCode(callareaCode);//传入拨打区号
callRecord.setCallingNumber(tokens[1]);//传入拨打号码
anwserareaCode = tokens[4];//接通地址
callRecord.setAnswerAddressAreaCode(anwserareaCode);//传入接通区号
callRecord.setAnswerNumber(tokens[3]);//传入接通号码
try {
time1 = df.parse(tokens[5]+" "+tokens[6]);
} catch (ParseException e1) {
e1.printStackTrace();
}

try {
time2 = df.parse(tokens[7]+" "+tokens[8]);
} catch (ParseException e) {
e.printStackTrace();
}

callRecord.setStartTime(time1);//开始时间
callRecord.setEndTime(time2);//结束时间
callRecords.add(callRecord);//添加用户记录
}

if(f==6)
{
callareaCode = tokens[2];//拨打区号
callRecord.setCallingAddressAreaCode(callareaCode);//传入拨打区号
callRecord.setCallingNumber(tokens[1]);//传入拨打号码
anwserareaCode = tokens[3].substring(0,4);//接通地址
callRecord.setAnswerAddressAreaCode(anwserareaCode);//传入接通区号
callRecord.setAnswerNumber(tokens[3]);//传入接通号码
try {
time1 = df.parse(tokens[4]+" "+tokens[5]);
} catch (ParseException e1) {
e1.printStackTrace();
}

try {
time2 = df.parse(tokens[6]+" "+tokens[7]);
} catch (ParseException e) {
e.printStackTrace();
}

callRecord.setStartTime(time1);//开始时间
callRecord.setEndTime(time2);//结束时间
callRecords.add(callRecord);//添加用户记录
}

}
}
}
// for(int i=0;i<callRecords.size();i++) {
// System.out.println(callRecords.get(i).getAnswerNumber()+" "+callRecords.get(i).getCallingNumber()+" "+callRecords.get(i).getCallingAddressAreaCode()+" "+callRecords.get(i).getAnswerAddressAreaCode());
// }
//

Collections.sort(users1,new Comparator<User>() {
public int compare(User s1,User s2){
double n1 = Double.parseDouble(s1.getNumber());
double n2 = Double.parseDouble(s2.getNumber());
if(n1 > n2) {
return 1;
}
return -1;
}

});
Collections.sort(users2,new Comparator<User>() {
public int compare(User s1,User s2){
double n1 = Double.parseDouble(s1.getNumber());
double n2 = Double.parseDouble(s2.getNumber());
if(n1 > n2) {
return 1;
}
return -1;
}

});

 在座机的基础上增加了手机,还有地区之分,比如市内打电话给省内,市内打电话给市内,市内打电话给省外等一系列的情况。好在没处理信息收费的情况,但是难度较于第一次还是有很大的提升。情况变得更复杂,就需要你的类的设计更加的合理,更有复用性,而且第一次如果不按照老师给的类图写,会比较难写。

三.踩坑心得

对于这几次作业的一个坑点,我觉得就是一开始要好好的读懂类图,然后通过类图去设计方法,这样比较方便也不会随意出错。要好好运用父类与子类的特点,这样可以减少重复的代码,提高写代码的效率,并且在后期维护或者说修改代码的时候可以方便很多。然后在类多了以后要清楚各个类的对象是否通用,很容易出错,或者是这个成员变量是否通用,要清楚父类与子类的关系。而且要清楚面向对象这个特点。

四.改进建议:

对于前这三次作业而言,我的代码一般都是大家的惯性思维,由于怕出错,所以都写得比较常规,有些题目确实有更简单的思路,但是我不知道怎么去运用哪些方法,可能是知识量储备的比较少吧。有不少是询问了同学之后才完成的。还有是对正则表达式认知的不到位,不知道怎么去正确使用正则表达式去筛选出输入格式错误的地方,如果将这个点弄明白的话,代码的复杂程度就会降低很多。而且其中还有不少是不按照常规方法写的,这对与后两次写的代码有点痛苦,不好续写。

五.总结

通过这三次的习题练习,我学到了挺多的东西。
比如说继承与多态,继承(inheritance) 机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础.上进行扩展,增加功能。这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构。体现了由简单到复杂的认识过程。
多态性(polymorphism) 多态性是考虑在不同层次的类中,以及在同一类中,同名的成员函数之间的关系问题。函数的重载,运算符的重载,属于编译时的多态性。以虚基类为基础的运行时的多态性是面向对象程序设计的标志题。函数的重载,运算符的重载,属于编译时的多态性。以虚基类为基础的运行时的多态性是面向对象程序设计的标志。

子类与父类
子类和父类的概念是在继承中才会有的,继承的前提是 is-a 原则,比如:Student is a Person,那么我们就可以表示为Student extends Person。

子类又叫派生类,子类一定具有父类的全部属性与行为,并且拥有的属性更多,具体的行为更加丰富,表示的范围更小;父类又名超类。

子类对象在进行实例化之前一定会首先实例化父类对象,先有父类对象才有子类对象,即先调用父类的构造方法之后再调用子类构造方法!
子类在继承父类时会继承父类的所有结构 (包括私有属性、构造方法、普通方法)。。

21206134-赵景涛-第三次blog总结的更多相关文章

  1. JAVA第三次blog总结

    JAVA第三次blog总结 0.前言 这是我们在博客园上第三次写博客,也是本学期最后一次的JAVA学习大总结.现在我们的JAVA已经接近尾声了,对于编程思想和方法的改变依旧是难点,但是经过这一段时间的 ...

  2. 第三篇Scrum冲刺博客

    第三篇Scrum冲刺博客 一.站立式会议 提供当天站立式会议照片一张 二.每个人的工作 成员 已完成工作 明天计划完成的工作 遇到的困难 林剑峰 初步完成用户界面 用户界面跳转到用户信息页面的按钮,设 ...

  3. python skimage图像处理(三)

    python skimage图像处理(三) This blog is from: https://www.jianshu.com/p/7693222523c0  霍夫线变换 在图片处理中,霍夫变换主要 ...

  4. 【RAC】 RAC For W2K8R2 安装--共享磁盘的配置(三)

    [RAC] RAC For W2K8R2 安装--共享磁盘的配置(三) 一.1  BLOG文档结构图 一.2  前言部分 一.2.1  导读 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学 ...

  5. 【书评:Oracle查询优化改写】第三章

    [书评:Oracle查询优化改写]第三章 BLOG文档结构图       导读 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的知识,~O(∩_∩)O~: ① 隐含参数 ...

  6. 怎么进入BAT的研发部门?

    怎么进入BAT的研发部门? ======================================剑指offer+leetcode+geeksforgeeks+编程之美+算法导论====秒杀BA ...

  7. 【整理】待毕业.Net码农就业求职储备

    声明:本文题目来源于互联网,仅供即将从学校毕业的.Net码农(当然,我本人也是菜逼一个)学习之用.当然,学习了这些题目不一定会拿到offer,但是针对就业求职做些针对性的准备也是不错的.此外,除了技术 ...

  8. Android 低功耗蓝牙的多设备连接与数据接收,简单实现

    在网络层,互联网提供所有应用程序都要使用的两种类型的服务,尽管目前理解这些服务的细节并不重要,但在所有TCP/IP概述中,都不能忽略他们: 无连接分组交付服务(Connectionless Packe ...

  9. Android Studio 插件 GsonFormat :你还在烦恼 为 Json格式 生成 JavaBean实体类吗?

    在网络层,互联网提供所有应用程序都要使用的两种类型的服务,尽管目前理解这些服务的细节并不重要,但在所有TCP/IP概述中,都不能忽略他们: 无连接分组交付服务(Connectionless Packe ...

  10. .net面试技术要点总结

    [整理]待毕业.Net码农就业求职储备   本文题目来源于互联网,仅供即将从学校毕业的.Net码农(当然,我本人也是菜逼一个)学习之用.当然,学习了这些题目不一定会拿到offer,但是针对就业求职做些 ...

随机推荐

  1. C#定时任务(Timer)

    新建Timer类 using BaseAsset.Data.Infrastructure; using BaseAsset.Data.Repositories; using BaseAsset.Ent ...

  2. java面经学习002

    2. Java都有哪些map,分别怎么实现的,具体讲 3. 除了LinkedHashMap,你还知道哪些有序map 4. ConcurrentHashMap讲一讲 5. 为什么要有线程池 6. 线程池 ...

  3. Spring Boot 启动时自动执行代码的几种方式

    来源:https://mp.weixin.qq.com/s/xHAYFaNBRys3iokdJmhzHA 前言 java自身的启动时加载方式 Spring启动时加载方式 代码测试 总结 1.前言 目前 ...

  4. 基于rabbitmq之MQTT协议的智能家居

    智能家居项目 智能可燃气体报警器 产品是一款可燃气体报警器,如果家中燃气泄露浓度到达一定阈值,报警器检测到并上传气体浓度值给后台,后台以电话.短信.微信等方式,提醒用户家中可能有气体泄漏. 用户还可能 ...

  5. 深入理解snp-calling流程——转载

    ------------恢复内容开始------------ GATK4流程 准备配套数据 明确参考基因组版本!!!b36/b37/hg18/hg19/hg38,记住b37和hg19并不是完全一样的, ...

  6. web端测试的测试点和注意事项【转载】

    文章来源:作者:simplesally 出处:https://www.cnblogs.com/simple1025/   [转载] 工作中接触了不同类型的web端系统,内容不同,需求不同,测试关注点也 ...

  7. Python基础数据类型-Number(数字)

    a = -1 # int b = 2.0 # float c = 13.11 # float d = 3.14j # complex print(type(a), type(b), type(c), ...

  8. 安装python及环境搭建

    操作系统是windows7 64位 打算使用visual studio code进行代码编写 1.先安装visual studio code去visual studio 官网下载VS code htt ...

  9. DevOps Gitlab环境部署

    DevOps 介绍 目录 DevOps 介绍 一.DevOps 介绍 1.1.1 DevOps 介绍 1.1.2 CI/CD简介 1.1.2 Gitlab安装与使用 一.DevOps 介绍 1.1.1 ...

  10. ElasticSeach性能调优

    1. 硬件相关 1.1 硬盘 一块好的硬盘,会带来ES整体性能10倍以上提升,推荐在datanode节点上使用SSD硬盘,索引的data目录,存放在SSD硬盘上. 1.2 内存 建议内存>128 ...