第二次Blog作业
作业自评
202016班 20201615
一.前言:
感觉这三次作业较前几次的作业相比难度加大了很多,暂且不说它的题目数量,它的难题不再只是一次作业只有一道题目,有的题目集难度就是很大!比如题目集四里难题就有两道,这两道题目都是需要花很多时间来理解,来揣摩题目的含义及如何按照题目要求去实现它。
这三次作业主要考察对正则表达式的熟练使用,对继承与多态的准确理解与应用,以及动态数组ArrayList<>的基本操作。例如在题目集3的7-1中有(水文数据校验及处理),这道题目真的比较难,需要java中的字符串处理类以及正则表达式对输入字符串数据进行合法性校验及计算。题目集3的7-2需要对日期问题面向对象设计,这用到Java中与类有关的构造方法等的相关知识点,有一点麻烦。题目集3的7-3没有太大难度,只是一个简单的继承,但是在题目集6中7-5这道题是基于上一道简单的图形继承的升华,在它的基础上增加了多态的熟练运用,以及各种各样的功能,难度虽然不大但是内容比较多,有一点麻烦。此外在题目集5中7-5(日期问题面向对象设计(聚合二)),这里也是对上次聚合一的升级化,类的设计需求很多,此外还有类的嵌套。
题目集6感觉都是对正则表达式的应用,要求我们熟练掌握Pattern、Matcher方法的运用,以及find、group对匹配到的数据进行处理,运用的知识点还有二维数组的创建及运用。Split关键字的运用,有时还有可能用到动态数组ArrayList的运用。此外还要分清楚find()和matches()的区别。
二.具体设计与分析:
下面是分析的要求:
①题目集4(7-2)、题目集5(7-4)两种日期类聚合设计的优劣比较
②题目集4(7-3)、题目集6(7-5、7-6)三种渐进式图形继承设计的思路与技术运用(封装、继承、多态、接口等)
③对三次题目集中用到的正则表达式技术的分析总结
④题目集5(7-4)中Java集合框架应用的分析总结
这是题目集4的7-2的类图,它的要求为 设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1900,2050] ,month∈[1,12] ,day∈[1,31]

此题为类的聚合,但是很多人在写这道题目时并没有完全按照要求来,直接单独创建3个单独的类,好像这3个类之间没有什么关系,其实不然,从类图可以轻松看出main方法中调用了DateUtil这个类,在DateUtil类中又调用了Day这个类,Day类再调用Month类等等,结构时很鲜明的,如果是不按照要求来写的话也就起不到对类的熟练应用的作用了。DateUtil类中有DateUtil的无参构造方法,有参构造方法,Day类的setter,getter函数,检查合法性函数等等,其中题目要求的3个测试功能的具体实现也都在DateUtil类中:
1.求下n天
2.求前n天
3.求两个日期相差的天数
下面是我的DateUtil类的设计与生成报表内容:


此类中的3个测试功能也没有太难,只是一些日期的处理,


聚合一总体来说是对类的一个串连,一层套一层的,关联性较高,因为每个类都是连接在一起的,若是后期的需要修改以及优化会产生很大的麻烦,改一处的话就要有很多地方的改动,耦合性太大,不利于程序的维护。并且将每个类都串在一起的话,代码的可读性很差。
下面我们来分析一下聚合二。
聚合二的类图与生成报表的内容如下:


此类图相对于聚合一来说,可以很直观地看出此时的Month类,Day类,Year类处于一个并列关系,这就是较聚合一最大的区别。下面来简单分析下聚合二:
很显然的是DateUtil类实现了聚合二的全部功能,DateUtil类的成员变量包括了Year,Month,Day类,方法中有这三种类的setter,getter方法,以及测试的3个主要功能。


DateUtil类里的东西很多,而Day,Month,Year类中就没有很多东西,除了类的结构与聚合一有较大区别外,聚合二中有些功能也是在聚合一的基础上完成的。例如输出语句会有上一个日期previo或者next is ,这需要记录一下先前的日期,或者对两处的值进行分开输出。
聚合二中的类分开实现,耦合性不大。如果需要改动代码,只需要改动当前类中的内容,整体代码不需要有太大的改动,并且聚合二代码可读性较强。
题目集4的7-3只是一个较简单的继承类问题,并没有涉及太多。Shape类中有一个求图形面积的方法。Circle类继承Shape类,自身有独自的半径radius属性。Rectangle类也继承了Shape类,自身有独自的长length和宽width属性。球体Ball类继承了Circle类,其自身有球体积的方法。长方体Box类,继承了Rectangle类,自身额外定义类高的属性height和求体积的方法,题目输出的时候会输出多条语句,这是因为创建子类对象时调用了父类和子类的构造方法。

题目6的7-5是在前面继承一题的基础上增加了较多内容,有多态的运用,下面为绘制的类图:

Shape类我定义为抽象类,因为其他3个类继承了Shape类,而且都有getarea()函数。判断数据合理性的方法和将其他数据类型转换为字符串String类型的方法。之后Circle类,Rectangle类,Triangle类都继承并重写了父类中的getarea()方法。同时他们都定义了各自的特有私有属性。主要使用了多态的方法能使得系统具有较好的可复用性。

题目6的7-6:实现图形接口及多态性 ,这道题目也不是很难,只是增加了一个接口。定义一个求面积的接口,内部有抽象的一个求面积的方法。然后按题目要求定义的Circle类和Rectangle类使用这个接口并重写里面的求面积方法。我个人感觉这道题目的接口类与抽象类很相似,也就是说并没有完全发挥接口的优势。

这里接口只有一个getarea()函数而已。其实接口内部的属性默认用final关键字修饰,方法默认并且只能使用抽象方法,有些东西没能够体现出来。下面直接上图:


下面分析正则表达式的运用:
题目集4的7-1,水文的数据校验与处理,题目要求的东西也挺多:
- 测量时间:格式为“年/月/日 时:分”,其中年份取值范围为[1,9999],“月”与“日”为一位数时之前不加“0”,日期与时间之间有一个空格,“时”与“分”之间采用冒号分隔(英文半角),“时”为一位数时之前不加“0”,“分”始终保持两位,且始终为“00”。注意:“时”数必须是24小时进制中的偶数值。这里的正则比较难写,要求太多了,下面是日期的正则,我自己写的也不太标准:"(\\s*[1-9]\\d{0,3})/(([1-9])|[1[0-2]])/(([1-9])|([1-2]\\d)|(3[0-1]))(([02468])|(1[02468])|(2[02])|0):00\\s*"
- 目标水位、实际水位、流量:均为实型数,取值范围为[1,1000), 小数点后保留1-3位小数或无小数(也无小数点)。水位格式的检验:"([1-9][0-9]{0,2}.[0-9]{1,3})|[1-9][0-9]{0,2}",
校验开度模式:"[1-9].[0-9]{2}",
- 目标开度、实际开度:实型数,取值范围为[1,10),必须保留2位小数,两个开度之间用“/”分隔对应的正则表达式的编译字符串可以是:"\\s*[1-9]\\.\\d{2}\\s*"。
- 分析这些编译字符串使用到的基础知识点有:
\\s 代表一个空字符(第一个\为转义符)
\\d 代表一个数字(第一个\为转义符)
{0,2} 使它前面的字符被重复0-2次
[0-9] 代表一个0~9的数字
[02468] 代表0、2、4、6、8中的一个数字
* 使他前面的字符匹配0或以上次
? 使它前面的字符匹配0或1次
. 可以代替任意一个字符
题目集6里的正则运用也比较多,有qq号校验,验证码校验,学号校验。但是这些都是比较基本的正则表达式,难度不是很大。QQ号的检验中用到了[1-9][0-9]{4,14},也是可以有多种写法,我写成”[1-9]\\d{4,14}”也可以,7-2 字符串训练-字符排序中用到了字符串转化字符数组,char an[]=str.toCharArray(); 7-3 正则表达式训练-验证码校验中用到了正则"[0-9a-zA-Z]{4}",开始的时候我写成find(),而不是matches(),这样就会有几个测试点不过,这是因为matches()的格式是严格要求的。7-4 正则表达式训练-学号校验,这题也不是很难,用到正则"2020((1[1-7])|61|(7[1-3])|(8[1-2]))([0-3][1-9])|(40)",情况有点复杂,所以用到的或者|有点多,这差不多就是这几次正则的内容了。
题目集5(7-4)中Java集合框架应用的分析总结: 这题统计Java程序中关键词的出现次数主要用到ArrayList动态数组,先用正则表达式分割一下输入的字符串,在对每一个字符串进行查找,这题的难度比较大,当时也没有学到set,map,所以没有得到满分。需要注意的是,创建的动态数组类型为字符串类型。
三.踩坑心得:
1.正则表达式的书写时要注意括号和或者,在验证学号和水文时我优势会绕很多弯路,验证学号时我开始写成了这样的:"2020((1[1-7])|61|(7[1-3])|(8[1-2]))(0[1-9])|(1[0-9])|(2[0-9])|(3[0-9])|(40)",这个与最终的我感觉相差不大,但是测试时就是不对。
2.判断正则是否查找到时用str.find(),然后它会一直向后查找,不会从头查找的,在关键字的匹配中对每一行的查找就算是用到这种特性,要不然处理起来就是非常麻烦。
3.str.find()和str.matches()是有较大差别的,matches是严格按照所写正则匹配的,不能有多余的字符出现。但是find就不一样,它会在需要查找的表列中查找,只要找到了就可以,有多余字符也没有事,通俗点说,就是查找不太严格,这在qq号的检测,验证码的检测,学号的检测中,都是用到精确查找。

4.在多态的书写中,父类的引用来生成子类时,属性编译时是看父类,调用时还是看父类,若是私有属性,在子类中也要定义一个属性。
四.改进建议:
在继承问题的时候可以多去尝试方法的形参用父类对象,传值时用子类对象。可以大大提高代码的复用性与可读性。同时父类的属性定义为私有属性更加严谨。
有些时候定义对象数组,可以方便我们的代码,如题目集6,7-5中我们可能对于一个类会定义多个对象并且要保留并使用他们各自的数据。使用数组或ArraysList动态数组都行。
五.总结:
在这几次的作业中,我了解到了正则表达式书写的规范性与多样性,其次,括号的加入也是至关重要的,在后面的字符捕获组中会有很大用处。动态数组ArrryList的使用真的是很好用的存在,数组元素及结构有极佳的可塑性,与一般数组的访问差别不是太大,可以考虑数组直接用它来替代。同时我进一步了解了java的封装性,继承,多态和接口。同时对这个强大的处理字符串的工具:正则表达式进一步了解并运用。不仅如此,代码的调试的方便性提高了编程的效率。

浙公网安备 33010602011771号