Java第二阶段总结 一、前言 二、作业过程总结 三、OO设计心得 四、测试的理解与实践 五、课程收获 六、对课程的建议
此篇博客是对Java第二阶段的三次作业做一个小结,这些题目是对Java语言知识点更深层次的挖掘,运用到了面向对象的三大技术特性:封装性-继承性-多态性,还学习了正则表达式的运用,是原先作业的更高级。
二、作业过程总结
①总结三次作业之间的知识迭代关系
第四次的作业是水文数据校验及处理、蒙特卡罗方法求圆周率 、图形继承,考的是对于正则表达式和继承关系的运用,尤其是正则表达式的运用。第五次的作业是图形继承与多态、一元多项式求导,考的是面向对象中的封装性、继承性以及多态性和正则表达式的运用,一元多项式求导分成了三部分利用正则表达式进行分割。第六次的作业是图形卡片排序游戏、图形卡片分组游戏和求素数,这里的作业接触到接口,又是一个新的知识点的运用,靠的是类的继承、多态性使用方法以及接口的应用。该阶段的作业题目有部分相似之处,如圆形的继承,有几题都用到了,还有图形面积的排序。
②如何通过作业逐步理解面向对象的封装性、继承性与多态性三大技术特性
通过第四、五、六次作业了解到了封装得作用,然后从第五、六作业初步了解了继承和多态得作用。封装性是将类的某些信息隐藏在类的内部,不允许外部程序进行直接的访问调用,通过该类提供的方法来实现对隐藏信息的操作和访问,隐藏对象的信息,留出访问的对外接口。继承性是子类继承父类得方法,但是不能继承父类的私有方法。多态性是同一行为具有多个不同表现形式或表现形体的能力。
③作业过程中遇到的问题及解决方法
问题 一 :第四次作业水文校验题目中出现了很多问题,如输入连续多个空值、每一列均有误及格式不对等
解决方法:询问很多同学,不断使用特殊示例得以解决,包括检验的正则表达式的反反复复修改
问题 二 :一元多项式求导题目思路出现了问题
解决方法:经过查询资料及检查发现如何分解每一项的系数和指数出现了逻辑上的问题,最后运用了三个正则表达式来解决这个问题,分别代表三部分:系数、X、指数(具体如下)
问题 三 :一元多项式求导题目中用long类型来计算超大型数据测试时会出现数据偏差的错误
解决方法:百度得知使用BigInteger来计算超大型数据不会出现此类问题,并且学到了如何使用BigInteger的乘法和减法(用法如下)
问题 四 :第六次作业第一题输入0时测试点答案错误
解决方法:询问同学得知要正常输出但没有数据而不是非法
问题 五 :第六次作业第二题输入0时测试点也答案错误
解决方法:原本以为跟第一题一样的情况,也是询问同学才知道这个地方要报非法“Wrong Format”
问题 六 :第六次作业出现了代码过长的问题
解决方法:提取了程序中多次重复利用的代码,写入shape类中,每当要使用时直接调用即可(具体代码如下)
1 import java.util.Arrays;import java.util.Scanner; 2 public class Main { 3 public static void main(String[] args) { 4 Scanner input = new Scanner(System.in); 5 String number;String num;Shape sh = new Shape(); 6 Circle ci = new Circle();Rectangle re = new Rectangle(); 7 Triangle tr = new Triangle();Trapezoid trape = new Trapezoid(); 8 double[] cili = new double[100];double[] cili2 = new double[100]; 9 double[] reli = new double[100];double[] reli2 = new double[100]; 10 double[] trli = new double[100];double[] trli2 = new double[100]; 11 double[] trapeli = new double[100]; 12 double[] trapeli2 = new double[100]; 13 double[] sumli = new double[100]; 14 String[] sortsumli = new String[100];String[] numli = new String[100]; 15 int i = 0;int smli = 0;int nums = 0; 16 int cil = 0;int rel = 0;int trl = 0;int trapel = 0; 17 int cil2 = 0;int rel2 = 0;int trl2 = 0;int trapel2 = 0; 18 double sortsums = 0;double sortsums2 = 0;double sortsums3 = 0;double sortsums4 = 0; 19 do { 20 num = input.nextLine().trim(); 21 numli = num.split(" "); 22 for (int l = 0; l < numli.length; l++) { 23 if (Integer.parseInt(numli[l]) > 4 || Integer.parseInt(numli[l]) < 0) { 24 System.out.println("Wrong Format"); 25 return; 26 } else { 27 nums++; 28 }} 29 } while (0 != Integer.parseInt(numli[numli.length - 1])); 30 if (nums == 1) { 31 System.out.println("Wrong Format"); 32 return; 33 } 34 number = input.nextLine().trim(); 35 if (number == null || number.equals("")) { 36 System.out.println("Wrong Format"); 37 return; 38 } 39 if (sh.validate(number)) { 40 for (int l = 0; l < numli.length; l++) { 41 switch (Integer.parseInt(numli[l])) { 42 case 1: 43 i = ci.validate(number, i); 44 if (i <= 0) { 45 System.out.println("Wrong Format"); 46 return; 47 } else { 48 cili = ci.S();sumli[smli] = cili[cil];smli++;cil++; 49 } 50 break; 51 case 2: 52 i = re.validate(number, i); 53 if (i <= 0) { 54 System.out.println("Wrong Format"); 55 return; 56 } else { 57 reli = re.S();sumli[smli] = reli[rel];smli++;rel++; 58 } 59 break; 60 case 3: 61 i = tr.validate(number, i); 62 if (i <= 0) { 63 System.out.println("Wrong Format"); 64 return; 65 } else { 66 trli = tr.S();sumli[smli] = trli[trl];smli++;trl++; 67 } 68 break; 69 case 4: 70 i = trape.validate(number, i); 71 if (i <= 0) { 72 System.out.println("Wrong Format"); 73 return; 74 } else { 75 trapeli = trape.S();sumli[smli] = trapeli[trapel];smli++;trapel++; 76 } 77 break; 78 } 79 } 80 System.out.println("The original list:"); 81 for (int l = 0; l < numli.length; l++) { 82 switch (Integer.parseInt(numli[l])) { 83 case 1: 84 if (l == 0) { 85 System.out.print("["); 86 } 87 System.out.print("Circle:" + String.format("%.2f", sumli[l]) + " "); 88 if (Integer.parseInt(numli[l+1]) == 0) { 89 System.out.print("]"); 90 } 91 sortsumli[l] = String.format("%.2f", sumli[l]) + "Circle"; 92 cili2[cil2] = sumli[l]; 93 cil2++; 94 break; 95 case 2: 96 if (l == 0) { 97 System.out.print("["); 98 } 99 System.out.print("Rectangle:" + String.format("%.2f", sumli[l]) + " "); 100 if (Integer.parseInt(numli[l+1]) == 0) { 101 System.out.print("]"); 102 } 103 sortsumli[l] = String.format("%.2f", sumli[l]) + "Rectangle"; 104 reli2[rel2] = sumli[l]; 105 rel2++; 106 break; 107 case 3: 108 if (l == 0) { 109 System.out.print("["); 110 } 111 System.out.print("Triangle:" + String.format("%.2f", sumli[l]) + " "); 112 if (Integer.parseInt(numli[l+1]) == 0) { 113 System.out.print("]"); 114 } 115 sortsumli[l] = String.format("%.2f", sumli[l]) + "Triangle"; 116 trli2[trl2] = sumli[l]; 117 trl2++; 118 break; 119 case 4: 120 if (l == 0) { 121 System.out.print("["); 122 } 123 System.out.print("Trapezoid:" + String.format("%.2f", sumli[l]) + " "); 124 if (Integer.parseInt(numli[l+1]) == 0) { 125 System.out.print("]"); 126 } 127 sortsumli[l] = String.format("%.2f", sumli[l]) + "Trapezoid"; 128 trapeli2[trapel2] = sumli[l]; 129 trapel2++; 130 break; 131 } 132 } 133 System.out.println(); 134 System.out.println("The Separated List:"); 135 sh.shortlist(cili2,reli2,trli2,trapeli2); 136 System.out.println(); 137 System.out.println("The Separated sorted List:"); 138 cili2 = sh.So(cili2);reli2 = sh.So(reli2);trli2 = sh.So(trli2);trapeli2 = sh.So(trapeli2); 139 sh.shortlist(cili2,reli2,trli2,trapeli2); 140 System.out.println(); 141 sortsums = sh.Sum(cili2); 142 sortsums2 = sh.Sum(reli2); 143 sortsums3 = sh.Sum(trli2); 144 sortsums4 = sh.Sum(trapeli2); 145 double[] sortsumsz = { sortsums,sortsums2,sortsums3,sortsums4}; 146 double max = Arrays.stream(sortsumsz).max().getAsDouble(); 147 System.out.println("The max area:" + String.format("%.2f", max)); 148 } 149 } 150 } 151 class Shape { 152 public double Sum(double[] so){ 153 double sum = 0; 154 for (int d = 0; d < so.length; d++) { 155 if (so[d] > 0) { 156 sum = sum + so[d]; 157 } 158 } 159 return sum; 160 } 161 public double[] So(double[] so){ 162 for (int l = 0; l < so.length - 1; l++) { 163 for (int j = l + 1; j < so.length; j++) { 164 if (so[l] < so[j]) { 165 double temp = so[l];so[l] = so[j];so[j] = temp; 166 } 167 } 168 } 169 return so; 170 } 171 public void shortlist(double[] cili2, double[] reli2, double[] trli2, double[] trapeli2) { 172 for (int l = 0; l < cili2.length; l++) { 173 if(l == 0 && cili2[l] == 0.0){ 174 System.out.print("[]"); 175 } 176 if (cili2[l] != 0) { 177 if (l == 0) { 178 System.out.print("["); 179 } 180 System.out.print("Circle:" 181 + String.format("%.2f", cili2[l]) + " "); 182 if (cili2[l + 1] == 0.0) { 183 System.out.print("]"); 184 } 185 } 186 } 187 for (int l = 0; l < reli2.length; l++) { 188 if(l == 0 && reli2[l] == 0.0){ 189 System.out.print("[]"); 190 } 191 if (reli2[l] != 0) { 192 if (l == 0) { 193 System.out.print("["); 194 } 195 System.out.print("Rectangle:" 196 + String.format("%.2f", reli2[l]) + " "); 197 if (reli2[l + 1] == 0.0) { 198 System.out.print("]"); 199 } 200 } 201 } 202 for (int l = 0; l < trli2.length; l++) { 203 if(l == 0 && trli2[l] == 0.0){ 204 System.out.print("[]"); 205 } 206 if (trli2[l] != 0) { 207 if (l == 0) { 208 System.out.print("["); 209 } 210 System.out.print("Triangle:" 211 + String.format("%.2f", trli2[l]) + " "); 212 if (trli2[l + 1] == 0.0) {System.out.print("]");}}} 213 for (int l = 0; l < trapeli2.length; l++) { 214 if(l == 0 && trapeli2[l] == 0.0){ 215 System.out.print("[]"); 216 } 217 if (trapeli2[l] != 0) {if (l == 0) {System.out.print("[");} 218 System.out.print("Trapezoid:"+ String.format("%.2f", trapeli2[l]) + " "); 219 if (trapeli2[l + 1] == 0.0) {System.out.print("]");}}}} 220 public boolean validate(String number) { 221 String[] num = new String[10000]; 222 num = number.split(" "); 223 for (int i = 0; i < num.length; i++) { 224 if (Double.parseDouble(num[i]) < 0) { 225 return false; 226 } else { 227 return true; 228 } 229 } 230 return false; 231 } 232 } 233 class Circle { 234 double[] n = new double[10000];double[] s = new double[10000];int b = 0;int x = 0; 235 public double[] S() { 236 for (int c = 0; c < n.length; c++) { 237 if (n[x] > 0) { 238 s[x] = Math.PI * n[x] * n[x]; 239 x++; 240 } 241 } 242 return s; 243 } 244 public int validate(String number, int i) { 245 String[] num = new String[10000]; 246 num = number.split(" "); 247 int a; 248 for (a = 0; a < 1; a++) { 249 if (Double.parseDouble(num[i]) <= 0) { 250 return 0; 251 } else { 252 n[b] = Double.parseDouble(num[i]); 253 i++;b++; 254 } 255 } 256 return i; 257 } 258 } 259 class Rectangle { 260 double[] n = new double[10000];double[] s = new double[10000]; 261 int a = 1;int b = 0;int x = 0;int z = 0; 262 public double[] S() { 263 for (int c = 0; c < n.length; c = c + 2) { 264 if (n[x] > 0 && n[a] > 0) { 265 s[z] = n[x] * n[a]; 266 a = a + 2;x = x + 2;z++; 267 } 268 } 269 return s; 270 } 271 public int validate(String number, int i) { 272 String[] num = new String[10000]; 273 num = number.split(" "); 274 int d; 275 for (d = 0; d < 2; d++) { 276 if (Double.parseDouble(num[i]) <= 0) { 277 return 0; 278 } else {n[b] = Double.parseDouble(num[i]);i++;b++;}} 279 return i;}} 280 class Triangle { 281 private double side1;private double side2;private double side3; 282 double[] n = new double[10000];double[] s = new double[10000]; 283 int a = 1;int b = 0;int d = 2;int v = 0;int g = 1;int h = 2; 284 double p = 0;int x = 0; 285 public double[] S() { 286 for (int c = 0; c < n.length; c = c + 3) { 287 if (n[x] > 0 && n[a] > 0 && n[d] > 0) { 288 p = (n[x] + n[a] + n[d]) / 2;double ts = p * (p - n[x]) * (p - n[a]) * (p - n[d]); 289 s[v] = Math.sqrt(ts);a = a + 3;d = d + 3;x = x + 3;v++;}} 290 return s;} 291 public int validate(String number, int i) { 292 String[] num = new String[10000];num = number.split(" ");int e; 293 for (e = 0; e < 3; e++) { 294 if (Double.parseDouble(num[i]) <= 0) { 295 return 0; 296 } else {n[b] = Double.parseDouble(num[i]);i++;b++;}} 297 for (int f = 0; f < n.length; f = f + 3) { 298 if (n[f] > 0 && n[g] > 0 && n[h] > 0) { 299 side1 = n[f];side2 = n[g];side3 = n[h]; 300 if (((side1 + side2) <= side3) || ((side1 + side3) <= side2) || ((side2 + side3) <= side1)) { 301 return 0;} 302 g = g + 2;h++;}} 303 return i;}} 304 class Trapezoid { 305 double[] n = new double[10000];double[] s = new double[10000];int x = 0; 306 int a = 1;int b = 0;int d = 2;int v = 0;int g = 1;int h = 2;double p = 0; 307 public double[] S() { 308 for (int c = 0; c < n.length; c = c + 3) { 309 if (n[x] > 0 && n[a] > 0 && n[d] > 0) { 310 s[v] = (n[x] + n[a]) * n[d] / 2;a = a + 3;d = d + 3;x = x + 3;v++; 311 }}return s;} 312 public int validate(String number, int i) { 313 String[] num = new String[10000];num = number.split(" "); 314 int e; 315 for (e = 0; e < 3; e++) { 316 if (Double.parseDouble(num[i]) <= 0) { 317 return 0; 318 } else {n[b] = Double.parseDouble(num[i]);i++;b++;}} 319 return i;} 320 }
④每次作业花费的时间比例 7 : 4 : 4
⑤对编程过程的严谨性的认识及教训
在题目中的超大型数据计算时我一开始使用的是long类型,但是在超大型数据计算时超过了最大长度之后,得出的数据值会出现很大的偏差;在一元多项式的题目中我们使用substring这个截取字段的方法,这个方法有个特点为“取头不取尾”需要我们多注意。
三、OO设计心得
①对面向对象三大技术特性之间关系的理解
封装、继承、多态。从一定角度来看,封装和继承几乎都是为多态而准备的。这是我们最后一个概念,也是最重要的知识点。封装:在一个对象内部,数据可以是私有的,不能被外界访问。通过这种方式,对象对内部数据提供了不同级别的保护,以防止程序中无关的部分意外的改变或错误的使用了对象的私有部分。像我们用private把数据被保护在内部,程序的其它部分只有通过被授权的操作getter和setter,才能对数据进行操作。继承:实现继承是指直接使用基类的属性和方法而无需额外编码的能力,接口继承是指仅使用属性和方法的名称、但是子类必须提供实现的能力。子类继承父类的方法,减少代码的重复性,自己也可以在内部构造自己的方法。多态:多态就是指一个类实例的相同方法在不同情形有不同表现形式,但通过一个公共的类,那些操作可以通过相同的方式予以调用。通过指向父类的引用,在不同子类中重写的方法。(有查阅资料)
②面向对象设计的基本原则理解(单一职责原则及“开-闭”原则)
单一职责:每个类里面都会有很多种方法,但是每一种方法只要做好自己的事情就好,并且方法与方法之间互不干涉,例如判断圆半径的合法性跟求圆的面积,都在Circle类里面,但是要写在Circle类不同的方法里面,
“开-闭”原则:当我们建了一个类之后,我们需要把类里面的属性都私有化,当外界进行访问时时无法访问的,所以我们需要写get和set方法,来给这些属性赋值和取它们的值。
③OO编程思维的理解
面向对象和之前学习的C语言以及刚开始接触的面向过程思想不一样,我认为是它们的升级版,当我们拿到题目时首先会去考虑有哪些对象,然后考虑对象具有哪些属性和方法,然后再考虑main方法的调用,考虑是否有输入输出值,整体思路很清晰,程序很明朗。当我们拿到一个题目时,我们会去分析有哪些对象,对象有哪些属性和方法,这些方法的作用是什么,这是在学习了面向对象后的思考模式。通过学习Java和C语言的过程中,Java更加人性化,我们会站在不同的对象的角度去思考问题。
④类设计心得
想先举个例子,比如今天上体育课,总共有三个学生小明小红小刚,他们分别有自己喜欢的项目,在这个地方进行设计时会考虑到建一个学生类,然后会想到需要两个基本属性姓名和爱好;又比如在控制台输入长方体的长宽高,需要输出该长方体的体积跟表面积,看到这个题目时,我们会自然想到需要建一个长方体类,里面需要三个参数和求表面积体积的两个方法。通过上面两个例子我们知道,当需要建一个类时,我们先需要获取题目中的各项信息,类具有哪些属性,需要书写哪些方法,便可以构成一个完整的类。
四、测试的理解与实践
①测试对于编码质量的重要性
测试的作用就是用来测试代码的运行是否流畅和测试代码的运行速度,减少了运行时间也是提高了代码的质量,测试的时候可以帮我们找到代码问题,我们还可以提炼代码,或许会想到更好的方法去实现题目要求,从而在减少了代码量的同时提高了代码的质量,并且可以让我们知道不同方式实现时得运行时间的对比,所以测试对于编码质量而言很重要。
②查阅资料,假设使用Junit进行程序的测试是否可行
通过查阅资料,测试可行,了解到这里用到的是junit的4.12的版本:
以上是加减乘除的验证,查阅资料还了解到单元测试需要遵循的规则:1、每一个测试方法上使用@Test进行修饰;2、每一个测试方法必须使用public void进行修饰;3、每一个测试方法不能携带参数;4、测试代码和源代码在两个不同的项目路径下;5、测试类的包应该和被测试类保持一致;6、测试单元中的每个方法必须可以独立测试。(junit也建议在每一个测试方法名加上test前缀,表明这是一个测试方法)
五、课程收获
教训及收获:很惨痛的教训是正则表达式学的太差,出现了很多纰漏,水文校验一道题磕了三天,到最后延时那天搞出来;还出现了很多小问题,审题不够仔细,漏空格或者字母打错都导致答案错误。学到的东西也很多,最大的收获便是学到了这三大特性的运用,还有正则表达式的检验,它的功能很强大,一个正则表达式模式可以检验很多东西。OO设计的基本原则除了之前的单一职责,还了解到“开-闭”原则,学到了get和set的用法。
六、对课程的建议
①第三阶段作业难度、题量的建议
作业难度可以在第三阶段稍稍提升一点,没有类图其实也增加了一点难度,我们需要花的时间会更多一点;作业题量建议和第二阶段差不多,两到三道题就好(毕竟最近各门课的作业和实验扎堆)。另外对题目的建议:1.希望多一些输出样例给我们参照;2.老师可以出一些结合前面所学知识点的题目让我们梳理前面所学的知识点,而不是断层的学。3.pta对的运行时间跟有效代码可否改为最后一个提交的,有时会受到网络影响造成运行超时,而且大家的想法肯定都在不断进步,只取第一次的代码可能会让人产生题目对了就行了的思想。
②课程内容讲解方面的建议
建议:每次的pta作业跟课堂作业希望老师都可以进行简单的点评跟讲解,其实也是在进行讨论,很多同学看到会讲出自己的想法,大家一起交流;还有一点就是希望老师把一些讲了的实例代码发群里,我们有空可以多敲敲看看看,如果看回放的话稍微有点麻烦。