第二阶段Blog作业:

前言:

前三次的知识点主要涉及到了数据格式的处理、聚合与继承、正则表达式的使用。

题目集4有三道题,7-1为水文数据校验及处理,主要考察的是对于字符串处理类CheckData、DealData的使用和对正则表达式的合理使用以及对指导书的正确解读,7-2给了类图,根据类图进行构建比较容易就能完成,图形继承主要是考察了继承的相关知识,三道题题量较为适中,7-1初步写起来偏难,其他两道较为简单,花费时间比为 5:2:2。

 

题目集5有五道题,前三道考察的是简单的数据处理问题,第四道统计关键字出现的次数考察了Map接口的使用以及正则表达式对数据的处理,第五道题为日期聚合一的升级版,结构更加合理,这几道题目个人感觉第五道题目较难,难在对正则表达式掌握的不够熟练以及思路不够清晰,其他五道题较为简单,五道题花费的时间比值为1:1:1:4:2。

 

题目集6有六道题,前四道为简单的正则表达式的运用,在经过前几次作业之后,这种程度的正则表达式应该是比较轻松就能完成的,第五道为图形的继承与多态,考察了对继承与多态的使用,第六道题为实现图形的接口及多态性考察了接口以及多态。这六道题前四道较为简单,后两道相较难一点,但是没有之前题目集有任务指导书的题难,写起来还算轻松。

六道题所画时间比例为1:1:1:1:2:2

设计与分析:

一、 题目集4 7-2与题目集5 7-4 两种日期类聚合设计的优劣比较

 题目集4 7-2是传统的类编写方式,通过定义不同的类,并在其内进行对象的嵌套,实现了多个相关类之间的相互调用。其主要结构为将Year类作为最底层的对象,依次嵌套在月,日类中,实现的日期的聚合,这样的结构使得类与类的嵌套与调用非常繁琐和复杂,当代码出现bug是难以定位,即使是debug也难以快速找到问题点。

 

题目集5 7-4的类设计显而易见的Year、Month、Day类相互独立,没有7-2的嵌套与绑定,当代码出现bug时可以快速找到问题点,并且这样的结构更加清晰明了,便于他人阅读。

 

 

二、 题目集4(7-3)、题目集6(7-5、7-6)三种渐进式图形继承设计的思路与技术运用(封装、继承、多态、接口等)

题目集4(7-3)通过子类继承父类,并重写父类的方法的方式,完成了对各种基本图形的属性和方法构造,通过继承,子类可以通过重写父类的方法,来完成对相同方法的不同体现,充分发挥继承的优点,通过在shape类中提供各种属性都需要有的方法,构造shape类。

class Shape{

            public void Show(){

                       System.out.println("Constructing Shape");

            }

            public double getArea(){

                       return 0.0;

            }         

}

让子类继承父类,重写父类方法

class Circle extends Shape{

            private double radius;

            public double getRadius() {

                       return radius;

            }

 

            public void setRadius(double radius) {

                       this.radius = radius;

            }

 

            public void Show(){

                       super.Show();

                       System.out.println("Constructing Circle");

            }

 

            Circle(){

                       super();

            }

            Circle(double r){

                       super();

                       this.radius=r;

            }

            public double getArea(){

                       return radius*radius*Math.PI;

            }

}

class Rectangle extends Shape{

            private double width;

            private double length;

            public void Show(){

                       super.Show();

                       System.out.println("Constructing Rectangle");

            }

            Rectangle(){

                       super();

            }

            Rectangle(double w,double l){

                       super();

                       this.width=w;

                       this.length=l;

            }

            public double getWidth() {

                       return width;

            }

 

            public void setWidth(double width) {

                       this.width = width;

            }

 

            public double getLength() {

                       return length;

            }

 

            public void setLength(double length) {

                       this.length = length;

            }

 

            public double getArea(){

                       return width*length;

            }

}

class Ball extends Circle{

 public void Show(){

  super.Show();

  System.out.println("Constructing Ball");

 

 }

 public Ball(double radius) {

  super(radius);

  }

 

 public double getArea(){

  return (super.getArea()*4);

 }

 

 public double getVolume(){

 

  return ((super.getRadius()*super.getArea()*4)/3);

 }

 

}

题目集6(7-5、7-6)中用的是抽象类和接口来实现继承。抽象类可以提供成员方法的实现细节,而接口中只能存在public abstract 方法,抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的,接口中不能含有静态代码块含有静态方法,而抽象类可以有静态代码块和静态方法,一个类只能继承一个抽象类,而一个类却可以实现多个接口,因为不同形状的图形有相同的属性,通过继承可以少写挺多代码进而减少代码的冗余,更能体现类之间的关系。图形的继承和多态让我第一次接触到了多态以及抽象类,封装和继承几乎是为多态而准备的,多态就是不同的对象对同一消息做出的不同响应。Shape作为抽象类,Circle,Rectangle,Triangle作为实体类,抽象类可以让类的设计有很好的扩展性和复用性。

7-5

 

7-6

 

interface GetArea {

 

            public double getArea();

           

}

class Circle implements GetArea {

 

            double radius;

           

            public  Circle(double radius) {

                       this.radius = radius;

            }

           

            @Override

            public double getArea() {

                       // TODO Auto-generated method stub

                       return Math.PI*radius*radius;

            }

 

}

class Rectangle implements GetArea {

 

            double width;

            double length;

            public Rectangle(double width ,double length) {

                       this.width = width;

                       this.length = length;

            }

            @Override

            public double getArea() {

                       // TODO Auto-generated method stub

                       return width*length;

            }

 

三、 三次题目中正则表达式技术的分析总结

三次题目中最难使用正则表达式的是水文数据的检测,需要对字符串进行分割后对每一个分割后的字符串进行检验,然后根据检验结果进行输,利用类的单一职责将每一部分封装成一个类,且一个类只负责该类的职责,通过类与类之间的聚合来实现整个过程,加深了对单一职责以及封装性的理解认识。字符串分割后产生的五部分还需要指出错误行以及列数,当检测到数据不合法是输出该行,行数可以通过设置 的计数器输出。

public static void main(String[] args) { Scanner ljy = new Scanner(System.in);

StringBuilder sb = new StringBuilder(ljy.nextLine()); String shuju = ljy.nextLine();

 

String exit = "exit"; int n=0;

int row = 0; while(shuju.equals(exit)==false){ sb.append('\n'+shuju);

n++;

shuju = ljy.nextLine();

}

String date = sb.toString(); if(date.matches("^\\s*|\\s*$")) { // System.out.println("Max Actual Water Level:0.00"); // System.out.println("Total Water Flow:0.00");

}

String []dates = date.split("\n"); int sum=0;

int count = 0 ; int flagdata=0; int flag2 = 0;

HydrologicalInfo[] flow = new HydrologicalInfo[1000]; DealData dealData = new DealData(dates[0]);

for(int i = 0;i<=n;i++) {

String []result = new String[5]; String []result1 = new String[2];

CheckData cheakDate = new CheckData(dates[i],n); if(cheakDate.validateData()==true)

{

flag2 = 0;

String data1=dates[i].trim();

//String []result = new String[5]; result = data1.split("\t");

String measureDateTime = result[0].trim(); String objectWaterLevel = result[1].trim(); String actualWaterLevel =result[2].trim(); String gateOpening = result[3].trim(); String waterFlow = result[4].trim(); result1 = gateOpening.split("/");

String objectGateOpening = result1[0].trim(); String actralGateOpening = result1[1].trim();

if(cheakDate.validateMeasureDateTime(measureDateTime)==false){ flagdata=1;

count = 1;

flag2 = 1;

System.out.println("Row:" + (i+1) + ",Column:" + count + "Wrong Format");

}

if(!cheakDate.validateWaterLevel(objectWaterLevel)){ count = 2;

flagdata=1; flag2 = 1;

System.out.println("Row:" + (i+1) + ",Column:" + count + "Wrong Format");

}

if(!cheakDate.validateWaterLevel(actualWaterLevel)){ count = 3;

flagdata=1; flag2 = 1;

System.out.println("Row:" + (i+1) + ",Column:" + count + "Wrong Format");

}

if(!cheakDate.validateGateOpening(objectGateOpening)){ count = 4;

flagdata=1; flag2 = 1;

System.out.println("Row:" + (i+1) + ",Column:" + count + "Wrong Format");

}

if(!cheakDate.validateGateOpening(actralGateOpening)){ count = 5;

 

flagdata=1; flag2 = 1;

System.out.println("Row:" + (i+1) + ",Column:" + count + "Wrong Format");

}

if(!cheakDate.validateWaterLevel(waterFlow)){ count = 6;

flagdata=1; flag2 = 1;

System.out.println("Row:" + (i+1) + ",Column:" + count + "Wrong Format");

}

}

else {

System.out.println("Wrong Format"); flagdata=1;

flag2 = 1;

}

if(flag2==1)

{

System.out.println("Data:"+dates[i]);

}

else {

double measureDateTime1 = Double.parseDouble(result[0]); double objectWaterLevel1 = Double.parseDouble(result[1]); double actualWaterLevel1 = Double.parseDouble(result[2]); double objectGateOpening1 = Double.parseDouble(result1[0]); double actralGateOpening1 = Double.parseDouble(result1[1]); double waterFlow1 = Double.parseDouble(result[4]);

HydrologicalInfo hydrologicalInfo = new HydrologicalInfo(objectWaterLevel1, actualWaterLevel1, objectGateOpening1, actralGateOpening1, waterFlow1);

flow[sum] = hydrologicalInfo; sum++;

}

}

if (flagdata==0 ){

for (int k = 0; k < sum; k++) {

if (flow[k].getActralGateOpening() > flow[k].getObjectGateOpening()) { System.out.println("Row:" + (k + 1) + " GateOpening Warning");

}

}

dealData.computeDate(flow,sum);

}

}

}

class CheckData{ private String data; private int row;

 

 

public CheckData(String data,int row) { this.data = data;

this.row = row;

}

 

public void setDate(String data ,int row) { this.data = data;

this.row = row;

}

public int getRow() { return row;

}

public void setRow(int row) {

this.row = row;

}

public String getData() { return data;

}

public void setData(String data) { this.data = data;

}

 

public boolean validateData() {

Pattern p = Pattern.compile("(.*)\\t(.*)\\t(.*)\\t(.*)\\t(.*)"); return p.matcher(data).matches();

}

除了关键字匹配和本题,其余题目的正则表达式都只需要做一个简单的匹配就行,和水文数据检测相比起来简单的多,只需把需要检验的数据拆分利用正则表达式进行检验,再利用正则表达出来的式子与输入的数据进行匹配,若可以匹配则输出true,不能输出则输出false。

 

QQ号检验:

public static void main(String[] args) {

                       // TODO Auto-generated method stub

                       Scanner input = new Scanner(System.in);

                       String s = input.next();

                      

                       String regex = "[1-9][0-9]{4,14}";

                      

                       boolean f = s.matches(regex);

                      

                       if(f == true) {

                                   System.out.println("你输入的QQ号验证成功");

                       }else {

                                   System.out.println("你输入的QQ号验证失败");

                       }

                      

            }

 

验证码校验:

String regex = "[A-Za-z0-9][A-Za-z0-9][A-Za-z0-9][A-Za-z0-9]";

 

特定规格的学号检验:

String regex = "2020(1[1-7]|6[1]|7[1-3]|8[1-2])(0[1-9]|[1-3][0-9]|4[0])";

 

四、 题目集5(7-4)中Java集合框架应用的分析总结

Collection是一个接口,是高度抽象出来的集合,它包含了集合的基本操作和属性。Collection包含了List和Set两大分支。List是一个有序的队列,每一个元素都有它的索引。第一个元素的索引值是0。List的实现类有LinkedList, ArrayList, Vector, Stack。Set是一个不允许有重复元素的集合。Set的实现类有HastSet和TreeSet。HashSet依赖于HashMap,它实际上是通过HashMap实现的;TreeSet依赖于TreeMap,它实际上是通过TreeMap实现的。Map是一个映射接口,即key-value键值对。Map中的每一个元素包含“一个key”和“key对应的value”。AbstractMap是个抽象类,它实现了Map接口中的大部分API。而HashMap,TreeMap,WeakHashMap都是继承于AbstractMap。Hashtable虽然继承于Dictionary,但它实现了Map接口。Iterator是遍历集合的工具,即我们通常通过Iterator迭代器来遍历集合。我们说Collection依赖于Iterator,是因为Collection的实现类都要实现iterator()函数,返回一个Iterator对象。ListIterator是专门为遍历List而存在的。再看Enumeration,它是JDK 1.0引入的抽象类。作用和Iterator一样,也是遍历集合;但是Enumeration的功能要比Iterator少。在上面的框图中,Enumeration只能在Hashtable, Vector, Stack中使用。

踩坑心得:

  • 提交的public class类名不为Main,比如,提交的类名如果是public class Main1就会出错。
  • 提交的代码中有多个public class。注意:提交的代码中只能有一个public class。
  • 复制的时候将程序第一行package也复制进来。
  • 最新版的PTA使用Open JDK 8,已经支持Java 8。估计还不支持Java 9,请不要用Java 9中的新语法。
  • 显示格式错误,一般是因为你的输出最后一行少了回车换行,或者每行的行尾多了空格之类的错误.

改进建议:

作业难度的话建议还是可以呈现梯形,这样做起来不会觉得那么困难。题量3~5题比较合理。

 

总结:这几次OO编程训练以来,逐渐养成面向对象的编程思维,一次次的加深我对其思想和设计的理解和体会。解决一个个问题实现一个个功能时,会想到一个个模块地去解决,同时也会遇到一点困难,逐步认识自己的不足,但解决之后就会有收获的,所谓”需求推动进步“。通过本阶段的作业,抛开基本的继承、多态,还学习到单一职责原则和“开-闭”原则,这样大大提高代码的质量,收获很大。

Posted on 2021-04-25 17:20  满洲里有海  阅读(57)  评论(0编辑  收藏  举报