OO第二次大作业——来自小白星球总结

一、前言

   第四次题目集:

    1.题目量为三题:7-1 水文数据校验及处理 ,7-2 日期问题面对对象设计(聚合一), 7-3 图形继承。

    2.知识点:(1)字符串String方法,例如:equals()、trim()、split()、maches()等进行字符串的分割、比较、匹配等操作;(2)使用private进行数据域的封装;(3)计算日期使用聚合进行类设计,即在一个类中有另一个类的实体引用(类中的类);(4)实现图形类的继承,并在子类中重写父类的方法;(5)使用正则表达式进行字符串的匹配划分处理。

    3.难度:总体难度不是很大,水文校验处理需要使用较多正则表达式的匹配,相对难一些,其他两题从算法上看相对简单。

  第五次题目集:

    1.题目量为四题:7-5 日期问题面对对象设计(聚合二),7-4 统计Java程序中关键词的出现次数,7-2 合并两个有序数组为新的有序数组,7-3 对整型数据排序。

    2.知识点:(1)在日期问题上使用聚合(已提供类图);(2)采用StringBuilder对字符串进行操作,可直接改变字符串本身,而不是生成新的对象;(3)使用String字符串的replace()和replaceAll()方法;(4)Pattern类用于编译正则表达式后创建一个匹配模式,Matcher类使用Pattern实例提供的模式信息对正则表达式进行匹配。Pattern.compile()和Pattern.matcher()方法;(5)将两个数组排序输出(选择排序);(6)使用插入排序、选择排序、冒泡排序对数组排序。

    3.难度:数组排序相对简单,日期问题在测试点上较第一次题目集更细,统计关键字有两个测试点未通过,没找到问题所在。

  第六次题目集:

    1.题目量为六题:7-1 正则表达式训练-QQ号校验,7-2 字符串训练-字符排序,7-3 正则表达式训练-验证码校验,7-4 正则表达式训练-学号校验,7-5 图形继承与多态,7-6 实现图形接口及多态性。

    2.知识点:(1)简单正则表达式校验;(2)类的继承多态使用;(3)图形接口及多态。

    3.难度:相对前两次题目集都更简单。

二、设计与分析

①题目集4(7-2)、题目集5(7-5)两种日期类聚合设计的优劣比较。

图为题目集4(7-2)源码在SourceMonitor中的分析图:

 图为题目集5(7-5)源码在SourceMonitor中的分析图:

分析:两次题目的圈复杂度都偏高。

两次题目类图比较分析:

题目集4(7-2)类图:

题目集5(7-5)类图:

题目提示类图:

 

 

 分析:两次类图其实差别应该不大,主要是算法上的健壮性进一步进行了修改,在做类聚合一的时候考虑的还算周全,和聚合二题目给的类图已经很接近。

 部分设计源码:

  1 //Year类
  2 class Year{
  3     int value;
  4     //默认构造方法
  5     public Year(){
  6     }
  7     //带参构造方法
  8     public Year(int value){
  9         this.value=value;
 10     }
 11     //getter
 12     public int getValue(){
 13         return value;
 14     }
 15     //setter
 16     public void setValue(int value){
 17         this.value=value;
 18     }
 19     //判断year是否为闰年
 20     public  boolean isLeapYear(){
 21         return ((value % 4 == 0 && value % 100 != 0) || value % 400 == 0);
 22     }
 23     //效验数据合法性
 24     public boolean validate(){
 25         return value <= 2020 && value >= 1820;
 26     }
 27     //年份加一
 28     public void yearIncrement(){
 29         value=value+1;
 30     }
 31     //年份减一
 32     public void yearReduction(){
 33         value=value-1;
 34     }
 35 }
 36 //Month类
 37 class Month{
 38     int value;
 39     Year year;
 40     //默认构造方法
 41     public Month(){
 42     }
 43     //带参构造方法
 44     public Month(int yearValue,int monthValue){
 45         this.year=new Year(yearValue);
 46         this.value=monthValue;
 47     }
 48     //value getter
 49     public int getValue(){
 50         return value;
 51     }
 52     // value setter
 53     public void setValue(int value){
 54         this.value=value;
 55     }
 56     //Year getter
 57     public Year getYear(){
 58         return year;
 59     }
 60     //Year setter
 61     public void setYear(Year year){
 62         this.year=year;
 63     }
 64     //日期复位(1)
 65     public void resetMin(){
 66         value=1;
 67     }
 68     //月份设置为12
 69     public void resetMax(){
 70         value=12;
 71     }
 72     //效验数据合法性
 73     public boolean validate(){
 74         return value >= 1 && value <= 12;
 75     }
 76     //月份加一
 77     public void dayIncrement(){
 78         value=value+1;
 79     }
 80     //月份减一
 81     public void dayReduction(){
 82         value=value-1;
 83     }
 84 }
 85 //Day类
 86 class Day{
 87     int value;
 88     Month month;
 89     int[] a ={31,28,31,30,31,30,31,31,30,31,30,31};
 90     //默认构造方法
 91     public Day(){
 92     }
 93     //带参构造方法
 94     public Day(int yearValue,int monthValue,int dayValue){
 95         this.month=new Month(yearValue,monthValue);
 96         this.value=dayValue;
 97     }
 98     //getter
 99     public int getValue(){
100         return value;
101     }
102     public Month getMonth(){
103         return month;
104     }
105     //setter
106     public void setValue(int value){
107         this.value=value;
108     }
109     public void setMonth(Month value){
110         this.month=value;
111     }
112     //日期复位(1)
113     public void resetMin(){
114         value=1;
115     }
116     //日期设为该月最大值
117     public void resetMax(){
118         value=a[month.getValue()-1];
119     }
120     //效验数据合法性
121     public boolean validate(){
122         if(this.getMonth().getYear().isLeapYear())
123             a[1]=29;
124         if(this.getMonth().validate()) {
125             return value >= 1 && value <= a[month.getValue() - 1];
126         }
127         else{
128             return false;
129         }
130     }
131     //日期加一
132     public void dayIncrement() {
133         value=value+1;
134     }
135     //日期减一
136     public void dayReduction() {
137         value=value-1;
138     }
139 }

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

1. 题目集4(7-3)图形继承 在SourceMonitor中的分析图和类图:

 

 

 

分析:继承是面对对象语法的三大特征之一,通过继承,子类获得了父类的成员变量和方法,通过关键字extends可以申明一个类是从另外一个类中继承而来的。例如:

1 class 父类{
2   .......     //成员变量、成员方法
3 }
4 class 子类 extends 父类{
5   .......   //类体
6 }

1.子类不能选择性继承父类;

   2.Java不支持多重继承,但一个类可以实现多个接口,从而克服单继承的缺点;

   3.构造方法不会被子类继承,但可以从子类中调用父类的构造方法。

重写:子类中的一个实例方法具有与父类中的一个实例方法具有相同的签名(指名称、参数个数、类型)和返回值时,称子类中的方法重写了父类中的方法。

使用super调用父类中重写的方法以及访问父类中被隐藏的字段

源码:

  1 package PTA4;
  2 import java.util.Scanner;
  3 
  4 public class Main3 {
  5     public static void main(String[] args){
  6         Scanner input = new Scanner(System.in);
  7         int option = input.nextInt();
  8         if(option == 1){  //
  9             double circle = input.nextDouble();
 10             if(circle >= 0) {
 11                 Circle c = new Circle();
 12                 c.setRadius(circle);
 13                 System.out.printf("Circle's area:%.2f", c.getArea());
 14             }
 15             else{
 16                 System.out.print("Wrong Format");
 17             }
 18             System.exit(0);
 19         }
 20         else if(option == 2){  //矩形
 21             double width = input.nextDouble();
 22             double length = input.nextDouble();
 23             if(width>=0 && length>=0) {
 24                 Rectangle r = new Rectangle();
 25                 r.setWidth(width);
 26                 r.setLength(length);
 27                 System.out.printf("Rectangle's area:%.2f",r.getArea());
 28             }
 29             else{
 30                 System.out.print("Wrong Format");
 31             }
 32             System.exit(0);
 33         }
 34         else {
 35             if(option == 3){ //
 36                 double circle = input.nextDouble();
 37                 if(circle>=0) {
 38                     Ball b = new Ball();
 39                     b.setRadius(circle);
 40                     System.out.printf("Ball's surface area:%.2f\n",b.getArea());
 41                     System.out.printf("Ball's volume:%.2f",b.getVolume());
 42                 }
 43                 else{
 44                     System.out.print("Wrong Format");
 45                 }
 46             }
 47             else {
 48                 if(option == 4){ //立方体
 49                     double width = input.nextDouble() ;
 50                     double length = input.nextDouble() ;
 51                     double height = input.nextDouble();
 52                     if(length>=0 && width>=0 && height>=0) {
 53                         Box box = new Box();
 54                         box.setWidth(width);
 55                         box.setLength(length);
 56                         box.setHeight(height);
 57                         System.out.printf("Box's surface area:%.2f\n",box.getArea());
 58                         System.out.printf("Box's volume:%.2f",box.getVolume());
 59                     }
 60                     else{
 61                         System.out.print("Wrong Format");
 62                     }
 63                 }
 64                 else{
 65                     System.out.print("Wrong Format");
 66                 }
 67             }
 68             System.exit(0);
 69         }
 70     }
 71 }
 72 //图形面积类
 73 class Shape{
 74     public Shape(){  //无参构造
 75         System.out.println("Constructing Shape");
 76     }
 77     public double getArea(){
 78         return 0.0;
 79     }
 80 }
 81 //圆面积类
 82 class Circle extends Shape{
 83     private double radius;
 84     //构造方法
 85     public Circle() {
 86         System.out.println("Constructing Circle");
 87     }
 88     //setter
 89     public void setRadius(double radius){
 90         this.radius = radius;
 91         }
 92      //getter
 93     public double getRadius() {
 94         return radius;
 95     }
 96     //计算面积
 97     public double getArea(){
 98         return Math.PI*radius*radius;
 99         }
100 }
101 //矩形面积类
102 class Rectangle extends Shape{
103     private double width;
104     private double length;
105     //构造方法
106     public Rectangle(){
107         System.out.println("Constructing Rectangle");
108     }
109     // width setter
110     public void setWidth(double width){
111         this.width = width;
112     }
113     //width getter
114     public double getWidth(){
115         return width;
116     }
117     //length setter
118     public void setLength(double length){
119         this.length = length;
120     }
121     //width getter
122     public double getLength(){
123         return length;
124     }
125     //计算面积
126     public double getArea(){
127         return length*width;
128     }
129 }
130 //球体积类
131 class Ball extends Circle{
132     //构造方法
133     public Ball(){
134         System.out.println("Constructing Ball");
135     }
136     //求球的表面积
137     public double getArea(){
138         return 4*Math.PI*super.getRadius()*super.getRadius();
139     }
140     //求球的体积
141     public double getVolume(){
142         return 4*Math.PI*super.getRadius()*super.getRadius()*super.getRadius()/3;
143     }
144 }
145 //立方体体积类
146 class Box extends Rectangle{
147     private double height;
148     //构造方法
149     public Box(){
150         System.out.println("Constructing Box");
151     }
152     //setter
153     public void setHeight(double height){
154         this.height = height;
155     }
156     //getter
157     public double getHeight(){
158         return height;
159     }
160     //求立方体的表面积
161     public double getArea(){
162         return 2*(super.getLength()*super.getWidth() + super.getLength()*height + super.getWidth()*height);
163     }
164     //求立方体的体积
165     public double getVolume(){
166         return super.getLength()*super.getWidth()*height;
167     }
168 }

2.题目集六7-5 图形继承与多态 在SourceMonitor中的分析图和类图:

 

 

分析: 多态在使用父类类型的引用abstract抽象,只能调用父类中定义的方法和变量,变量不能被重写,重写只针对方法。覆盖时动态绑定,重载是静态绑定,用instanceof操作符测试一个对象是否是一个对象的实例,instanceof返回值是true或false。

方法看右侧,属性看左侧。先访问父类的构造方法再访问子类的构造方法。

源码:

  1 package PTA6;
  2 import java.util.ArrayList;
  3 import java.util.Collections;
  4 import java.util.Scanner;
  5 public class Main5{
  6     public static void main(String[] args) {
  7         ArrayList<Double> sumarea = new ArrayList<>();   //面积表
  8         Scanner input = new Scanner(System.in);
  9         int m = input.nextInt();  //m表示圆的数量
 10         int n = input.nextInt();  //n表示长方形的数量
 11         int p = input.nextInt();  //t表示三角形的数量
 12        // int p = m+2*n+3*t;  //一共要输入的边长,按顺序存入数组中
 13         if(m>=0 && n>=0 && p>=0) {  //数量输入合法
 14             Circle c[] = new Circle[m];
 15             Rectangle r[] = new Rectangle[n];
 16             Triangle t[] = new Triangle[p];
 17 
 18             //圆面积
 19             for (int i = 0; i < m; i++) {
 20                 c[i] = new Circle(input.nextDouble());
 21                 if (!c[i].validate()) {
 22                     System.out.print("Wrong Format");
 23                     System.exit(0);
 24                 }
 25                 sumarea.add(c[i].getArea());
 26             }
 27             //矩形面积
 28             for(int j = 0; j < n; j++){
 29                 r[j] = new Rectangle(input.nextDouble(), input.nextDouble());
 30                 if(!r[j].validate()){
 31                     System.out.print("Wrong Format");
 32                     System.exit(0);
 33                 }
 34                 sumarea.add(r[j].getArea());
 35             }
 36             //三角形面积
 37             for(int k = 0; k < p; k++){
 38                 t[k] = new Triangle(input.nextDouble(), input.nextDouble(), input.nextDouble());
 39                 if(!t[k].validate()){
 40                     System.out.print("Wrong Format");
 41                     System.exit(0);
 42                 }
 43                 sumarea.add(t[k].getArea());
 44             }
 45             Show show = new Show();
 46             show.showAll(sumarea);
 47             show.showAddsum(sumarea);
 48             show.showSort(sumarea);
 49             show.showAddsum1(sumarea);
 50         }
 51         else{
 52             System.out.print("Wrong Format");
 53         }
 54     }
 55 }
 56 //图形父类
 57 abstract class Shape{
 58     public Shape(){  //无参构造
 59     }
 60     public double getArea(){
 61         return 0.0;
 62     }
 63     public boolean validate(){
 64         return true;
 65     }
 66 }
 67 class Show{
 68     //输出表中面积
 69     public void showAll(ArrayList<Double> sumarea){
 70         System.out.println("Original area:");
 71         for(double i: sumarea){
 72             System.out.printf("%.2f ",i);
 73         }
 74         System.out.println();
 75     }
 76     //对面积求和
 77     public void showAddsum(ArrayList<Double> sumarea){
 78         System.out.print("Sum of area:");
 79         double sum = 0;
 80         for(double i: sumarea){
 81             sum +=i;
 82         }
 83         System.out.printf("%.2f",sum);
 84         System.out.println();
 85     }
 86     //对面积排序
 87     public void showSort(ArrayList<Double> sumarea){
 88         System.out.println("Sorted area:");
 89         Collections.sort(sumarea);
 90         for(double i: sumarea){
 91             System.out.printf("%.2f ",i);
 92         }
 93         System.out.println();
 94     }
 95     //对面积求和
 96     public void showAddsum1(ArrayList<Double> sumarea){
 97         System.out.print("Sum of area:");
 98         double sum = 0;
 99         for(double i: sumarea){
100             sum +=i;
101         }
102         System.out.printf("%.2f",sum);
103     }
104 }
105 //圆面积类
106  class Circle extends Shape {
107     private double radius;
108     //无参构造方法
109     public Circle() {
110     }
111     //带参构造方法
112     public Circle(double radius){
113         this.radius = radius;
114     }
115     //setter
116     public void setRadius(double radius){
117         this.radius = radius;
118     }
119     //getter
120     public double getRadius() {
121         return radius;
122     }
123     //判断是否合法
124     @Override
125     public boolean  validate(){
126         if(radius > 0)
127             return true;
128         else
129             return false;
130     }
131     //计算面积
132     @Override
133     public double getArea(){
134         return Math.PI*radius*radius;
135     }
136 }
137 //矩形面积类
138 class Rectangle extends Shape {
139     private double width;
140     private double length;
141     //构造方法
142     public Rectangle(){
143     }
144     //带参构造函数
145     public Rectangle(double width, double length){
146         this.width = width;
147         this.length = length;
148     }
149     // width setter
150     public void setWidth(double width){
151         this.width = width;
152     }
153     //width getter
154     public double getWidth(){
155         return width;
156     }
157     //length setter
158     public void setLength(double length){
159         this.length = length;
160     }
161     //width getter
162     public double getLength(){
163         return length;
164     }
165     //判断是否合法
166     @Override
167     public boolean  validate(){
168         if(width>0 && length>0)
169             return true;
170         else
171             return false;
172     }
173     //计算面积
174     @Override
175     public double getArea(){
176         return length*width;
177     }
178 }
179 //三角形面积类
180 class Triangle extends Shape{
181     private double side1;
182     private double side2;
183     private double side3;
184    public Triangle(){  //无参构造
185    }
186    //带参构造
187     public Triangle(double side1, double side2, double side3){
188        this.side1 = side1;
189        this.side2 = side2;
190        this.side3 = side3;
191     }
192    //side1 getter
193     public double getSide1() {
194         return side1;
195     }
196     //side1 setter
197     public void setSide1(double side1){
198        this.side1 = side1;
199     }
200     //side2 getter
201     public double getSide2() {
202         return side2;
203     }
204     //side2 setter
205     public void setSide2(double side2) {
206         this.side2 = side2;
207     }
208     //side3 getter
209     public double getSide3() {
210         return side3;
211     }
212     //side3 setter
213     public void setSide3(double side3) {
214         this.side3 = side3;
215     }
216     //判断是否合法,三边大于零且任意两边之和大于第三边
217     @Override
218     public boolean validate(){
219        if(side1<side2){
220            double temp = side1;
221            side1 = side2;
222            side2 = temp;
223        }
224        if(side1<side3){
225            double temp = side1;
226            side1 = side3;
227            side3 = temp;
228        }
229        if(side1>0&&side2>0&&side3>0&&(side2+side3)>side1)
230            return true;
231        else
232            return false;
233     }
234     //计算面积(海伦公式)
235     @Override
236     public double getArea(){
237        double p = (side1+side2+side3)/2;
238        return Math.sqrt(p*(p-side1)*(p-side2)*(p-side3));
239     }
240 
241 }

3.题目集合7-6 实现图形接口及多态性 在SourceMonitor中的分析图和类图:

 分析:抽象方法是指没有方法体的实体,同时抽象方法还必须使用关键字abstract做修饰,而拥有抽象方法的类就是抽象类,抽象类要使用abstract关键字声明。例如:

1 abstract class A{
2         public void fun(){  //普通方法
3             System.out.print("存在方法体的方法");      
4 }      
5          public abstract void print();  //抽象方法,没有方法体,有abstract做修饰
6 }

注:抽象类的使用原则:

1.抽象类必须为public或者protected(因为如果private,则不能被子类继承,子类便无法实现该方法),缺省情况下默认为Public;

2.抽象类方法不能直接实例化,需要依靠子类采用向上转型的方式处理;

3.抽象类必须有子类,使用extends继承,一个子类只能继承一个抽象类;

4.子类(如果不是抽象类)则必须覆写抽象类之中的全部抽象方法(如果子类中没有实现父类抽象的方法,则必须将该子类也定义为abstract类)。

源码:

 1 package PTA6;
 2 import java.util.Scanner;
 3 public class Main6 {
 4     public static void main(String[] args){
 5         Scanner input = new Scanner(System.in);
 6         double radius = input.nextDouble();  //输入圆半径
 7         double width = input.nextDouble();  //输入宽
 8         double length = input.nextDouble(); //输入高
 9         Circle1 c = new Circle1(radius);
10         Rectangle1 r = new Rectangle1(width,length);
11         if(c.validate()&&r.validate()) { //输入合法
12             GetArea m = new Circle1(radius);
13             System.out.printf("%.2f",m.getArea());
14             System.out.println();
15             GetArea n = new Rectangle1(width,length);
16             System.out.printf("%.2f",n.getArea());
17         }
18         else{
19             System.out.print("Wrong Format");
20         }
21     }
22 }
23 //圆面积类
24 class Circle1 implements GetArea{
25     private double radius;
26     //无参构造方法
27     public Circle1() {
28     }
29     //带参构造方法
30     public Circle1(double radius){
31         this.radius = radius;
32     }
33     //setter
34     public void setRadius(double radius){
35         this.radius = radius;
36     }
37     //getter
38     public double getRadius() {
39         return radius;
40     }
41     //判断是否合法
42     public boolean  validate(){
43         if(radius > 0)
44             return true;
45         else
46             return false;
47     }
48     //计算面积
49     public double getArea(){
50         return Math.PI*radius*radius;
51     }
52 }
53 //矩形面积类
54 class Rectangle1 implements GetArea{
55     private double width;
56     private double length;
57     //构造方法
58     public Rectangle1(){
59     }
60     //带参构造函数
61     public Rectangle1(double width, double length){
62         this.width = width;
63         this.length = length;
64     }
65     // width setter
66     public void setWidth(double width){
67         this.width = width;
68     }
69     //width getter
70     public double getWidth(){
71         return width;
72     }
73     //length setter
74     public void setLength(double length){
75         this.length = length;
76     }
77     //width getter
78     public double getLength(){
79         return length;
80     }
81     //判断是否合法
82     public boolean  validate(){
83         if(width>0 && length>0)
84             return true;
85         else
86             return false;
87     }
88     //计算面积
89     public double getArea(){
90         return length*width;
91     }
92 }
93 //面积接口类
94 interface GetArea {
95     public abstract double getArea();
96 }

③对三次题目集中用到的正则表达式技术的分析总结。

1.去除多余空格

1 s.trim()

2.时间合法性检验,测量时间:格式为“年/月/日 时:分”,其中年份取值范围为[1,9999],“月”与“日”为一位数时之前不加“0”,日期与时间之间有一个空格,“时”与“分”之间采用冒号分隔(英文半角),“时”为一位数时之前不加“0”,“分”始终保持两位,且始终为“00”。注意:“时”数必须是24小时进制中的偶数值。

1 String time="(?:(?( [1-9]| 1[0-9]| 2[0-3]| 00):00))";
2 String regex1="(?:((?:([1-9]([0-9]{0,3}))/((?:(([1-9]|(1[0-2]))/(?:([1-9]|([1-2][0-8])|19))))|(?:(([13578])|([1][02])(/31)))|(?:(([13-9]|1[02])/(29|30)))))(?:(?:( [02468]| 1[02468]| 2[02]|):00))))";
3 String regex2="(?:((?:([48]|[2468][048]|[13579][26]))|((?:(([1-9]([0-9]?))?:(0[48]|[2468][048]|[13579][26])))|(?:([48]|[2468][048]|[13579][26])00))/2/29)(?:(?:( [02468]| 1[02468]| 2[02]|):00)))";
4 String regexend=regex1+"|"+regex2;

3.目标水位、实际水位、流量:均为实型数,取值范围为[1,1000), 小数点后保留1-3位小数或无小数(也无小数点)。

1 String water ="(?:(?:(([1-9]([0-9]{0,2})))(?:((.[0-9]{1,3})?))))"

4.目标开度、实际开度:实型数,取值范围为[1,10),必须保留2位小数,两个开度之间用“/”分隔。

1 String hot="(?:(([1-9])(?:(.[0-9]{2}))))";

5.判断输入是否以 ‘ | ’分割五段。

1 return this.getData().trim().split("\\|").length == 5;

6.以空格替代注释‘//’和‘""’的内容。

1 return line.replaceAll("//.*", " ").replaceAll("\".*\"", " ");

7.以空格替代注释‘/* */’里的内容。

1 return word.toString().replaceAll("/\\*\\s*.*\\s*\\*/", " ");

8.以空格替代’{ }’。

1 return arry.replace("{","").replace("}","");

9.QQ号校验,要求必须是 5-15 位,0 不能开头,必须都是数字。

1 return str.matches("[1-9][0-9]{4,14}");

10.验证码校验,由四位数字或者字母(包括大小写)组成的字符串。

1 return str.matches("[a-zA-Z-0-9]{4}");

11.学号校验,对软件学院2020级同学学号进行校验,学号共八位,规则如下:

  • 1、2位:入学年份后两位,例如20年
  • 3、4位:学院代码,软件学院代码为20
  • 5位:方向代码,例如1为软件工程,7为物联网
  • 6位:班级序号
  • 7、8位:学号(序号)
1  return s.matches("2020((1[1-7])|(61)|(7[1-3])|(8[1-2]))(0[1-9]|1[0-9]|2[0-9]|3[0-9]|40)");

总结: 1.常用元字符需要牢记:

2.常用的校验:

  • 验证一年的12个月:"^(0?[1-9]|1[0-2])$"正确格式为:"01"~"09"和"1"~"12"。
  • 验证一个月的31天:"^((0?[1-9])|((1|2)[0-9])|30|31)$"正确格式为;"01"~"09"和"1"~"31"。
  • 验证用户密码:"^[a-zA-Z]"w{5,17}$"正确格式为:以字母开头,长度在6~18之间,只能包含字符、数字和下划线。

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

  在题目实现中,并未用到集合框架。查询相关资料,对集合框架做了一个初步了解。

  什么是集合框架?

  Java集合类主要由两个根接口Collection和Map派生出来的,Collection派生出了三个子接口:List、Set、Queue(Java5新增的队列),因此Java集合大致也可分成List、Set、Queue、Map四种接口体系,(注意:Map不是Collection的子接口)。

  集合体系中常用的实现类,分别是ArrayList、LinkedList、ArrayQueue、HashSet、TreeSet、HashMap、TreeMap等实现类。

  ArrayList是一个动态数组,也是我们最常用的集合,是List类的典型实现。它允许任何符合规则的元素插入甚至包括null。每一个ArrayList都有一个初始容量(10),该容量代表了数组的大小。随着容器中的元素不断增加,容器的大小也会随着增加。在每次向容器中增加元素的同时都会进行容量检查,当快溢出时,就会进行扩容操作。所以如果我们明确所插入元素的多少,最好指定一个初始容量值,避免过多的进行扩容操作而浪费时间、效率。ArrayList擅长于随机访问元,同时ArrayList是非同步的。

  Map接口采用键值对Map<K,V>的存储方式,保存具有映射关系的数据,因此,Map集合里保存两组值,一组值用于保存Map里的key,另外一组值用于保存Map里的value,key和value可以是任意引用类型的数据。key值不允许重复,可以为null。如果添加key-value对时Map中已经有重复的key,则新添加的value会覆盖该key原来对应的value。常用实现类有HashMap、LinkedHashMap、TreeMap等。

三、踩坑心得

1.题目集5中7-5 日期问题面对对象设计(聚合二),测试点提示为整型数最大值/最小值测试,开始以为输入需要使用BigInterger进行改进,后来发现是算法错误。

2.在求下n天的整型数最大值测试的测试点花费了较长时间。原因是:如果前一年是闰年,2月天数被置成29,而在后面算法中并没有更改过来,因此造成一个bug,测试了很多的数据才发现该错误,测试源码如下:

 1 //其下n天
 2     public DateUtil getNextDays(int n) {
 3         int[] a = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
 4         int sum; //当前年份剩余值
 5         if (this.getDay().getMonth().getYear().isLeapYear()) {  //如果是闰年
 6             a[2] = 29;
 7         }
 8         int y = this.getDay().getMonth().getYear().getValue();   //y为年份
 9         int m = this.getDay().getMonth().getValue();  //m为月份
10         int d = this.getDay().getValue();   //d为日期
11         sum = a[m] - d;
12         //计算当前年份剩余天数
13         if(m != 12){
14             for (int i = m + 1; i <= 12; i++) {
15                 sum = sum + a[i];
16             }
17         }
18         //sum = sum + a[m] - d;
19         //在同一年
20         if (sum > n) {
21             //在同一月
22             if (n + d <= a[m]) {
23                 d = d + n;
24             }//if
25             //不在同一月
26             else {
27                 n = n - (a[m] - d);  //除去当月后的剩余天数
28                 int i = m + 1;
29                 while (n > a[i]) {
30                     n = n - a[i];
31                     i++;
32                 }
33                 m = i;
34                 d = n;
35             }//else
36         }//if
37         //不在同一年
38         else {
39             n = n - sum;
40             int i = y + 1;
41             int days = 365;
42             if (new Year(i).isLeapYear()) {  //如果是闰年
43                 days = 366;
44             }
45             // int k = n;
46             while (n - days > 0) {
47                 i++;
48                 n = n - days;
49                 days = 365;
50                 if (new Year(i).isLeapYear()) { //判断当前i+1是否是闰年
51                     days = 366;
52                 }
53             }//while
54             y = i; //当前年份
55             //如果是一月
56             if (n <= a[1]) {
57                 m = 1;
58             }//if
59             //如果不是一月
60             else {
61                 if (new Year(y).isLeapYear()) { //当前年份是不是闰年
62                     a[2] = 29;
63                 }//if
64                 else{
65                     a[2]= 28;
66                 }
67                 int j = 1;  //从二月开始判断他有几个月
68                 // n = n-31; //减去一月的天数
69                 // int t = n;
70                 while (n - a[j] > 0) {
71                     n = n - a[j];
72                     j++;
73                 }//while
74                 // y = i;
75                 m = j;
76             }//else
77             d = n;
78         }//else
79         return new DateUtil(d, m, y);
80     }

3.题目集4 7-1 水文数据校验及处理中,应该是测试点不够严谨,输出格式显示为结尾无空行,我在编写程序的时候还一度不知道如何处理,在调试过程中找到基础错误后提交就直接通过了。

四、改进建议

1.对于7-5 日期问题面向对象设计(聚合),可以对类进行一个封装,设计类图中很多方法并未使用到,没有完全达到一个封装与聚合的效果,还可以改进。

2.对于7-4 统计Java程序中关键字的出现次数,还存在两个测试点未通过, 在编程中,并未使用到集合框架进行关键字的输出排序,还有待改进。

3.正则表达式校验题目,掌握的还不够熟练,一些表达式还可以进行简化。

五、总结

   相比于第一次大作业,在JAVA编程思想上有了较大的转变,写程序开始以设计类和方法的思想去思考问题,而不是以面对过程的思想,经过这三周的题目集训练。对整个面对对象JAVA有了一个更加深入的了解。初步掌握了面对对象的三大特性:封装、继承和多态。以及初步接触了接口。封装就是把描述一个对象的属性和行为封装在一个类中,使用private修饰的属性将不被公开或直接被其它对象访问,其他类只能通过调用get和set方法来引用;继承就是在一个已经存在的类基础上定义和实现一个新类,该类可以通过extends来实现对父类的继承,在子类中可以加入新的内容或者通过重写父类的方法,使用super不仅可以引用父类的构造方法,也可以引用父类的方法;多态就是在声明时使用父类,在实现或调用具体的子类,在不修改程序代码就可以改变程序运行所绑定的具体代码,让程序可以选择多个运行状态;接口interface 就是从几个类中派生出一个子类,继承它们所有的属性和方法,其解决了JAVA不支持多重继承的缺点,注:接口是一种特殊的抽象类,只包含常量和方法的定义,而没有变量和方法和实现。然后就是在正则表达式的验证上还不太熟练。

posted @ 2021-11-10 20:49  小白写博客  阅读(51)  评论(0)    收藏  举报