OOP作业总结(二)
关于OOP第二阶段的作业总结
阅读提示:本文目录导航,PC端页面位于文章右侧,移动端点击文章标题右侧小图标,需下滑后(顶部图片消失)目录才完全显示,可根据目录跳转文章位置。
一、前言
题目集四
- 知识点: 正则表达式,类的聚合关系,类的继承,多态,方法重写。
- 题量: 较小
- 难度:
\( \begin{split} &7-1 \quad ★★★✩✩ \\&7-2 \quad ★★✩✩✩ \\&7-3 \quad★✩✩✩✩ \end{split} \)

题目集五
- 知识点: Java实现冒泡,选择,插入排序,HashMap,正则表达式,类的聚合。
- 题量: 适中
- 难度:
\( \begin{split} &7-1 \quad ★✩✩✩✩ \\&7-2 \quad ★✩✩✩✩ \\&7-3 \quad ★✩✩✩✩ \\&7-4 \quad ★★★✩✩ \\&7-5 \quad ★★✩✩✩ \end{split} \)

题目集六
- 知识点: 正则表达式,接口,类的继承和多态。
- 题量: 适中
- 难度:
\( \begin{split} &7-1 ★✩✩✩✩ \\&7-2 ★✩✩✩✩ \\&7-3 ★✩✩✩✩ \\&7-4 ★✩✩✩✩ \\&7-5 ★★✩✩✩ \\&7-6 ★★✩✩✩ \end{split} \)

二、设计与分析
(1) 题目集四(7-2)、题目集五(7-5)两种日期类聚合设计的优劣比较
题目集四(7-2):

题目集五(7-5):

优劣:
题目集四(7-2)中Month聚合Year,Day聚合Month,DateUtil聚合Day。
题目集五(7-5)中DateUtil聚合Year,Month,Day。
前者能在Day中对Month,Year判断和增减,可以调用到Year和Month对象,但嵌套调用比较繁琐。高耦合,低内聚。
public void dayIncrement() {
if (value == getDaysOfMonth(month)) {
month.monthIncrement();
resetMin();
} else value++;
}
public DateUtil getNextNDay(int n) {
Day nday = day;
for (int i = 1; i <= n; ++i) {
nday.dayIncrement();
}
return new DateUtil(nday.getValue(), nday.getMont().getValue(), nday.getMonth().getYear().getValue();
}
后者在DateUtil中操作Day,Month,Year对象,但对于日期增减引发的变化需要在此类中完成。高内聚,低耦合。
(2) 题目集4(7-3)、题目集6(7-5、7-6)三种渐进式图形继承设计的思路与技术运用
题目集4(7-3):

二维图形继承三维图形,利用继承提高代码的复用性。开闭原则的体现,面向修改关闭,面向拓展开放。
题目集6(7-5):

Rectangle,Circle, Triangle均继承自抽象类 Shape,Shape实现Comparable,重写compareTo()使三种图形可比较面积。使用ArraysList<Shape> 存储,可直接使用Collections.sort()
abstract class Shape implements Comparable<Shape> {
public abstract double getArea();
public abstract boolean validate();
@Override
public int compareTo(Shape shape) {
return Double.compare(getArea(), shape.getArea());
}
@Override
public String toString() {
return String.format("%.2f", getArea());
}
public static double areaSum(ArrayList<Shape> shapes) {
double area = 0;
for (Shape aShape : shapes) {
area += aShape.getArea();
}
return area;
}
}
题目集6(7-6):

Rectangle、Circle均实现GetArea接口,不同类的相同行为。
(3)三次题目集中用到的正则表达式技术的分析总结
题目集4(7-1) 水文数据校验:
需要校验的数据大致如下:
2015/8/2 4:00|133.8400|133.070|1.11/1.21|75.780
2015/8/2 6:00|133.840|133.080|11.11/1.11|72.8a0
2015/8/2 8:00|133.830|133.070|1.11/1.11|73.890
2015/8/2 10:00|133.820|133.080|1.11/1.11|74.380
exit
设计思路:
String[] singleDataList = data.split("\\|");
先把每行数据根据|分割, 如果不能分割出5份(singDataList.length != 5)则属于Wrong Format。分割完成后,再对分割出的5部分单独校验。
1.日期
"[1-9][0-9]{0,3}/([1-9]|1[0-2])/([1-9]|[1-2][0-9]|3[0-1])\\s((1?[02468])|(2[02]))\\:00"
正则表达式可拆分编写,太长不利于维护,查错。
以上并未校验闰年2月情况太多不适合用正则表达式,借助日期合法校验类。
public static boolean checkDay(String str) {
//得 - 分割
String ss = str.replaceAll("/", "-");
ss = ss +":00";
SimpleDateFormat sd = new SimpleDateForma("yyyy-MM-dd HH:mm:ss");//括号内为日期格式,y代表份,M代表年份中的月份(为避免与小时中的分钟数m冲突,处用M),d代表月份中的天数
try {
sd.setLenient(false);//此处指定日期/时间解析是不严格,在true是不严格,false时为严格
sd.parse(ss);//从给定字符串的开始解析文本,以生一个日期
} catch (Exception e) {
return false;
}
return true;
}
2.水位,流量
"[1-9][0-9]{0,2}(\\.[0-9]{1,3})?"
3.开度
"[1-9]\\.([0-9]{2})\\s*/\\s*[1-9]\\.([0-9]{2})"
题目集5(7-4)统计Java程序中关键词的出现次数:
1.去除空格
StringBuilder check = new StringBuilder(all.toString().replaceAll("\\s+", ""));
2.处理""
str = str.replaceAll("\"(.*)\"", " ");
3.处理注释
StringBuilder(all.toString().replaceAll("/\\*(.*)\\*/", " ")); all = new StringBuilder(all.toString().replaceAll("\\[(.*)\\]", " "));
4.处理非字母数字字符
StringBuilder(all.toString().replaceAll("[^a-zA-Z0-9]", " "));
题目集6(7-1)QQ号校验:
if (s.matches("[1-9][0-9]{4,14}"))
题目集6(7-3)验证码校验:
if (s.matches("[0-9a-zA-Z]{4}"))
题目集6(7-4)学号校验:
if (s.matches("2020(1[1-7]|61|7[1-3]|8[1-2])(0[1-9]|[1-3][0-9]|40)"))
(4)题目集5(7-4)中Java集合框架应用的分析总结
先将所有关键字存入List
List<String> kewWordList = Arrays.asList("abstract", "assert", "boolean", "break", "byte", "case", "catch", "char", "class", "const",
"continue", "default", "do", "double", "else", "enum", "extends", "false", "final", "finally",
"float", "for", "goto", "if", "implements", "import", "instanceof", "int", "interface", "long",
"native", "new", "null", "package", "private", "protected", "public", "return", "short", "static",
"strictfp", "super", "switch", "synchronized", "this", "throw", "throws", "transient", "true", "try",
"void", "volatile", "while");
遍历分解后的文本,使用HashMap,关键字作为key,数量作为value建立映射关系,若单词在List中存在,则对应的value++。
Map<String, Integer> ans = new HashMap<>();
String[] singleWordList = all.toString().split("\\s+");
for (String keyWord : kewWordList) {
ans.put(keyWord, 0);
}
for (String singleWord : singleWordList) {
if (kewWordList.contains(singleWord)) {
ans.replace(singleWord, ans.get(singleWord) + 1);
}
}
使用replace()来更新key对应的value。
三、踩坑心得
题目集4(7-1) 水文数据校验:

1.日期合法性考虑不完善,正则表达式未考虑闰年2月和30天,31天的月份。
使用checkDay()对日期进行二次校验。
题目集5(7-4)统计Java程序中关键词的出现次数:
1.未考虑\* *\注释方法。
2.据说字符数超过800之后的部分关键词不计入才得分。(测试数据又有问题????)

题目集5(7-5)日期问题面向对象设计(聚合二):
求前n天,后n天用 \(O(n)\) 的求法超时了,一次应该+/-一个月或一年。
四、改进建议
题目集5(7-5)日期问题面向对象设计(聚合二),判断是否满月,减去当月的天数,复杂度任很高,判断满年可继续降低时间复杂度。
五、总结
- 学到了什么: 通过本阶段的学习,进一步掌握了正则表达式的使用。进一步了解了封装,继承,多态,接口,抽象类。
- 进一步学习: 七大设计原则的实际体现,体会其优点。
- 课程建议及意见: 课程自由度高,给学生充分的自学时间,作业循序渐进,梯度适中,无需要改进的地方。
但PTA作业的 测试数据反复出锅,麻烦修正一下。

浙公网安备 33010602011771号