Week02-Java基本语法与类库
1. 本周学习总结
本周讲了Java的基本数据类型,主要分为八类(byte
,short
,int
,long
,double
,float
,char
,boolean
),其中前四个是整型数据,一般为十进制数的形式,但也可以二进制,八进制或者十六进制的形式来展现。对于char型的字符,需要用单引号括起来,若是字符串型则要用双引号。对于浮点数类型,若为float型需要加上f的后缀,若为double则可以加上d的后缀或者不加后缀。但是用浮点型的数据进行计算往往不精确,若要进行精确ed浮点计算要用到BigDecimal类。
str.length()
用于获取字符串长度;str.indexOf(substr)
用于查找字符串;str.substring(int begin,int end)
用于截取字符串;str.equal(String str1)
用于判断字符串是否相等,若是str.equalsIgnoreCase(String str1)
还可忽略大小写判断相等;str.split(String sign)
则可以用于分割字符串。另外,在创建字符串时,可以使用StringBuilder
,这样可以大大提高其效率。 最后是关于数组的操作,也有很多实用的工具可使用,但是因为其数组一旦创建,就无法改变其大小,所以Java中引入了ArrayList类
,其近似数组却可以自动调节容量,所以使用起来也很方便。 2. 书面作业
1.String-使用Eclipse关联jdk源代码
1.1 查看String对象的源代码(截图),分析String使用什么来存储字符串?
以上是String对象的源代码的部分截图。 答:通过其源码可以看出String类其实是通过char数组来保存字符串的。1.2 分析其构造函数public String(char value[])
的作用?
答:public String(char value[])通过char数组构造一个字符串对象。
1.3 阅读public String replace(char oldChar, char newChar)
方法的代码,回答String的不可变性在该函数中如何体现?(重点)
public String replace(char oldChar, char newChar)
的源码如下:
public String replace(char oldChar, char newChar) { if (oldChar != newChar) { int len = value.length; int i = -1; char[] val = value; /* avoid getfield opcode */ while (++i < len) { if (val[i] == oldChar) { break; } } if (i < len) { char buf[] = new char[len]; for (int j = 0; j < i; j++) { buf[j] = val[j]; } while (i < len) { char c = val[i]; buf[i] = (c == oldChar) ? newChar : c; i++; } return new String(buf, true); } } return this; }
由上述代码可以看出字符串在进行替换时,创建了一个新的字符数组来存储替换以后的字符串,而不会改变原先的字符串。
下面是由实例来说明replace()如何体现String的不可变性。
public class Replace { public static void main(String[] args) { String str1 = "abcde"; String str2 = str1.replace("a", "A"); System.out.println(str1); System.out.println(str2); System.out.println(str1==str2); System.out.println(); String str3 = "abcde"; String str4 = str1.replace("f", "F"); System.out.println(str3); System.out.println(str4); System.out.println(str3==str4); }}
该程序的运行结果为:
由此可以看出,当字符串发生改变后,原先的字符串不会发生变化,而是会产生一个新的字符串,而如果字符串未发生改变则不会产生新的字符串,返回的还是原先的字符串。
1.4 简述String与字符数组的关系,使用字符数组就可以处理字符串,为什么还需要String呢?
答:String是一个类,而字符数组是一个数组,并且通过上面String的源码也看可看出String也是由字符数组构成的,使用字符数组来处理问题虽然更灵活,但是它不如String来的方便,使用String可以加快处理字符串的速度。
2.StringBuilder
2.1 结合PTA 5-2(StringBuilder) ,说明为什么频繁修改字符串时,应该使用StringBuilder而不是String?
答。在pta的第二题中如果使用String来进行字符串的拼接,因为字符串的不可变性,则当要将0至1000的数字拼接起来,每次拼接都要创建个新的字符串,所以其花费的时间是很长的,而使用StringBuilder则可以很好的解决这个问题。
通过下面一段代码更可以直观的看出两种方法额效率情况。public class STRINGBUILDER { public static void main(String[] args) { String str = ""; long start = System.currentTimeMillis(); for(int i=0;i<10000;i++){ str = str+i; } long end = System.currentTimeMillis(); long time = end - start; System.out.println("Sting消耗时间:" + time); StringBuilder str2 = new StringBuilder(""); start = System.currentTimeMillis(); for (int j = 0; j < 10000; j++) { str2.append(j); } end = System.currentTimeMillis(); time = end - start; System.out.println("StringBuilder消耗时间:" + time); }}
运行结果:
2.2 阅读jdk文档,查询StringBuilder的append(char[] str)
方法功能是什么?试分析StringBuilder内部使用什么来存放字符?调用StringBuilder的append(char[] str)
方法时,是如何实现添加字符的操作?
答:append(char[] str)
的方法是把指定字符数组按顺序添加到StringBuilder的对象中。在它内部使用char[]数组来存放字符到字符串缓冲区中,它是通过将传入进去的字符转换成字符数组后添加到StringBuilder对象中去。
3.字符串与字符串池
3.1 尝试使用字符串池的概念解释如下程序段输出结果,并回答这段代码创建了几个字符串对象:String str1 ="hi", str2="hi"; String str3 = new String(str1) System.out.println(str1==str2);
答:这题输出结果为true,共创建了两个字符串对象。因为当str1被赋值为”hi”时,会将”hi”存入字符串池,当str2也被赋值为”hi”时,会先搜索字符串池,看是否有相同的值,有的话就直接调用这个值,所以str1和str2使用了同一个地址的字符。而str3用了new String
,因此重新创建了一个字符串对象
3.2 重点:对基本类型我们可以使用==比较两个值是否相等,对于引用类型(如String, Integer、数组等)为什么不能使用==比较?应该怎样比较他们的值是否相等呢?
答:比较运算符”==”比较的是两个字符串的内存地址是否相同,因此两个字符串的内容相同,但内存地址也可能不同,因此不能用”==”比较。
要比较它们的值是否相等,应该使用equals()
方法,若要忽略大小写,还可以使用equalsIgnoreCase()
方法。 4.Wrapper(包装类)
4.1 Integer i = 100;
//100是基本类型,i是引用类型,为什么可以将100赋值给i?Integer x = 100; int y = x+1;x++;
这一串命令中包含了些什么操作?
答:可以将100赋值给i这用到了java中的自动装箱的功能,其可以将基本数据类型自动转换为对应的对象。
Integer x = 100; int y = x+1;x++;
中先自动装箱将100转换为Integer类型,然后自动拆箱将Integer类型转换为int类型,最后一个语句先拆箱再装箱。 4.2 Java为什么有了基本数据类型,还需要其包装类呢?包装类能给我们带来什么好处呢?
答:Java是一种面向对象的语言,但是基本数据类型却不是面向对象的,其基本数据类型之间的转换比较麻烦,为此定义了包装类可以方便的实现基本数据类型之间的转换。
5.实验总结
5.1 结对编程实践:使用结对编程的方式完成本周编程题目,即两个人同时合作完成实验题目(可1题也可多题,但最好是是两个人都没做过的题目)。推荐实施步骤:1.两个人坐在同一台电脑屏幕前判题,讨论、决定大概由谁先写。2. 1个人先编5分钟(自己商量多少分钟),同时另一个人观察对方编程或者查相关资料。3. 5分钟后,简单讨论后,换另外一个人继续编(请一定要换,另一个人如果无法接受应由第一个人讲解大概思路以方便其接受)。并完成如下作业:a.描述结对队友姓名、结对过程,提供非摆拍的两人在讨论、细化和编程时的结对照片。b.结对编程真的能够带来1+1>2的效果吗?通过这次结对编程,请谈谈你的感受和体会(如是否有利于自己编程水平的提高、是否有利于开拓编程思路)。
结对队友姓名:廖文姑。
结对题目:实验二中Math类应用的2.1 我觉得结对编程或许可以带来比两个人单独编程更好的效果,但是对我来说似乎没有很适用,我做题的时候如果有了思路,就不希望在中途再去听别人的思路,要听的话也应该是我写完自己的题以后再和别人去讨论是否有更加方便的做法。就像这次,我们在编程中都有自己的思路,所以在统一解题思路时还是有了很多争论,比如输出形式之类的,感觉这样花的时间会更长诶,所幸这题并没有很难,最后还是写了出来。5.2 PTA-1综合小测验
答:对于综合测验主要考察的还是一些简单的函数编写以及对于字符串常用操作,其中斐波那契数列运用了递归的方法,可以比较方便的实现该函数,然后为了能够在search
中进行对sort
中排序好的数组进行搜索,需要在循环外定义好一个数组,然后将sort的值存储在该数组中,另外使用Array.toString()的方法可以实现对数组内的数进行输出并使用”[]”包裹。最后的截取身份证的出生年月主要使用了字符串截取str.substring()
的方法。
5.3 PTA-3身份证排序。并回答:使用sort2
方法进行排序可以对出生年月日进行升序排序,如果现在有需要对其进行降序排序,或者按照其中的出生月份排序,怎么解决呢?
答:这题的身份证排序和第一题的获取身份证信息有类似的地方,但是相较之下多了排序,对于sort1
,可以直接截取出字符串然后转换成相应格式后使用Arrays.sort()
函数进行排序输出,但是sort2
的话,因为排序后要输出的是整个身份证,因此不能使用Arrays.sort()
函数,所以我选择了用冒泡法进行排序。
5.4 PTA-4动态数组
答:这题相较其他题目来说较为简单,主要考察二维数组。唯一的坑大概就是输出格式的问题,题目要求前一个字符串的开头到后一个字符串的开头中间要隔着七个字符串,因为没考虑到后面数字较大的进行乘法得到的字符串长度会 有所改变,所以之前想当然的在两个字符串间加了两个空格,最后当然是格式错误……后来使用了%-7s
的输出形式来处理输出才得到了正确答案。
5.5 (重点:小测题目)PTA-8 ArrayList入门。并回答:为什么有了数组还要使用ArrayList?
答:这题题目虽然看起来多,但是其实大部分是解题步骤,所以也算简单。只要能够熟练ArrayList的方法,例如atr.add()
,str.contain()
,str.indexOf()
,str.lastIndexOf()
,str.get()
,str.remove()
等,解决起来就很简单了。
5.6 选做:5-5(浮点数计算), 5-6(枚举), 5-7(大整数相加)
5-5(浮点数计算)实验总结
这题用到了大数字操作类中的java.math.BigDecimal类,要注意的是因为使用浮点数计算会不精确,所以应该将数据实例化为字符串形式进行操作。5-6(枚举)实验总结
这题运用了枚举的方法,注意要将将Grade getGrade(int score)
函数放到外面定义的一个类中去,然后在main函数中通过switch语句调用函数来实现输出操作。 5-7(大整数相加)实验总结
这题用到了大数字操作类中的java.math.BigInteger类,然后使用equalsIgnoreCase()
方法进行对大小写E的判断。然后之前没看清题目,误以为是只需要输入两个数字,后来才发现是可以多个数字相加,所以看懂题目意思也很重要啊…… 6.选做:公交卡里应该还有多少钱?请分析原因
答:公交卡里应该已经欠费,将图片中的余额转化为十六进制溢出了,实际上得到的是一个负数。7.选做(难):package与javac、 java、 -classpath、 -d与Eclipse
在 com.ibm
包中编写 StringUtil类,内有一方法
public static void foo1(){ System.out.println(StringUtil.class+" method:foo1"); }
在edu.jmu
包中编写Main类,调用com.ibm.StringUtil的foo1方法。 7.1 尝试用命令行进行编译并运行,截图
在edu.jmu
包中编写Main类,其中掉了com.ibm.StringUtil的foo1方法
7.2 将生成的StringUtil.class放到d:\lib下正确的目录结构下,将Main.class放到d:\test下正确的目录结构,尝试在命令行下运行,并截图。
7.3 Eclipse中自己编写的源代码放在哪个目录、class文件放在哪个目录(给出绝对目录)?在Eclipse项目中按一下Ctrl+F11
就可以直接运行Main,当按下Ctrl+F11时,到底在哪个目录下执行了什么样的java命令?
源代码目录:D:\Java\j\Java001\Java201621123031\JavaCode\src
D:\Java\j\Java001\Java201621123031\JavaCode\bin
按下Ctrl+F11
后,eclipse将bin目录下的.class文件进行编译输出。 3. 码云及PTA
3.1. 码云代码提交记录
在码云的项目中,依次选择“统计-Commits历史-设置时间段”,然后搜索并截图
3.2 截图题集“Java基本语法”PTA提交列表
3.3 使用老师发的jar程序统计每周的代码量
周次 | 总代码量 | 新增代码量 | 总文件数 | 新增文件数 |
---|---|---|---|---|
2 | 607 | 607 | 15 | 15 |
4. 小任务(加分)
2.1.新建n个大小的数组,往数组中随机填入1-100之间的整数(写成函数形式),然后统计并输出其中大于50与小于等于50的百分比(写成函数形式)。(注意:可以使用for each循环进行统计,随机数用法见参考资料)
代码截图
运行结果截图:2.4编写一个简单密码生成器类SimplePasswordGenerator,内含一个方法:public static String generate(int length)
,可以产生length长度的简单密码,该密码由大写字母、小写字母、数字组成。注意:小写字母中不应包含小写字母L。
加分考核点:(选做)构造大小为26的char数组,随机生成n个从a-z的字符,最后统计输出每个字符占总生成字符的百分比。
•打印数组:参见Arrays.toString….方法
代码截图: 运行结果截图:代码截图:
运行结果截图: