《Java技术》第二次作业
(一)学习总结
1.学习使用Eclipse关联jdk源代码,查看String类的equals()方法,截图,并学习其实现方法。举例说明equals方法和==的区别。
截图

在此处使用程序无法正常运行。
区别:
1、equals方法比较两个对象的内容
2、比较两个对象在内存中的首地址是否相同
举例:
public static void main(String[] args) {
String s1 = new String("hello world");
String s2 = new String("hello world");
System.out.println("两个内容相同但首地址不同的字符串比较结果为:");
System.out.println(s1.equals(s2));
System.out.println(s1 == s2);
截图

2.什么是构造方法?什么是构造方法的重载?下面的程序是否可以通过编译?为什么?
(1)构造方法主要是作用于类中的属性初始化,在构造方法时方法名称必须与类名称相同且不能有任何返回值的声明且在构造方法时不能不能使用return返回一个值。
(2)构造方法的重载就是好几个方法名称都相同,只是传递参数个数或者类型不同,作用于让类以统一的方式处理不同类型的数据;
此程序不能通过编译,因为 Foo obj = new Foo(); 处没有传递参数,
3.运行下列程序,结果是什么?查阅资料,分析为什么。
(1)结果是不等于0.3.
(2)原因是:在C/C++,Java,等编程语言中使用了使用了“IEEE 754浮点数格式”来存储浮点类型(float 32,double 64),通俗点说就是在十进制与二进制的转换中出现了精度损失的问题。
(3)通过对教材p378部分内容的学习,我将程序的修改如下:
package org.lxh.demo11.numberdemo;
import java.math.BigDecimal;
class MyMath
{
public static double add(double d1,double d2,double d3)
{
BigDecimal b1 = new BigDecimal(d1);
BigDecimal b2 = new BigDecimal(d2);
BigDecimal b3 = new BigDecimal(d3);
return b1.add(b2).add(b3).doubleValue();
}
public static double round(double d,int len)
{
BigDecimal b1 = new BigDecimal(d);
BigDecimal b2 = new BigDecimal(1);
return b1.divide(b2,len,BigDecimal.ROUND_HALF_UP).doubleValue();
}
}
public class Test {
public static void main(String args[]) {
double a = 0.1;
double b = 0.1;
double c = 0.1;
double d = MyMath.round(MyMath.add(a,b,c),1);
if(d == 0.3){
System.out.println("等于0.3");
}else {
System.out.println("不等于0.3");
}
}
}
截图

4.运行下列程序,结果是什么?分析原因,应如何修改.
结果无法正常运行。
原因是arr[1].value的赋值没有正常进行。
应修改为
public class Test {
public static void main(String[] args) {
MyClass arr=new MyClass();
arr.value=100;
}
}
class MyClass{
public int value=1;
}
截图

5.在一个10000次的循环中,需要进行字符串的连接操作,那么,应该使用String类还是StringBuffer类,为什么?性能有差异吗?能否写出测试代码证明你的结论。(可查阅资料)
使用StringBuffer类。
因为String类对象为不可变对象,StringBuffer类对象为可修改对象(可通过append()方法来修改值),
而String一旦修改了对象的值就等于重新创建并释放原有的对象,所以在多次的循环中String类的性能远不如StringBuffer类。
String类:
public class Test {
public static void main(String[] args) {
String tempstr = "abcdefghijklmnopqrstuvwxyz";
int times = 5000;
long lstart1 = System.currentTimeMillis();
String str = "";
for (int i = 0; i < times; i++)
{
str += tempstr;
}
long lend1 = System.currentTimeMillis();
long time = (lend1 - lstart1);
System.out.println(time);
}
}
运行结果如图:

StringBuffer类:
public class Test {
public static void main(String[] args) {
String tempstr = "abcdefghijklmnopqrstuvwxyz";
int times = 5000;
long lstart2 = System.currentTimeMillis();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < times; i++) {
sb.append(tempstr);
}
long lend2 = System.currentTimeMillis();
long time2 = (lend2 - lstart2);
System.out.println(time2);
}
}
运行结果如图:

根据运行结果可以看到StringBuffer类是String类速度的200多倍。
(二)实验总结
实验内容:
1.评分系统:一共10个评委,满分10分,假设有5个选手,分别由评委打分,去掉一个最高分和一个最低分后的平均分为该选手得分,将选手的得分从高到低进行输出。定义适当的方法。
程序设计思路
(1)声明义一个整形的动态数组用来存放评委的十个评分,
(2)用双重循环分别输入五个选手的十个评分并在输入每个选手的评分后进行冒泡排序,去掉数组的第一个和最后一个值即为去掉最高评分和最低评分,
(3)再声明一个float型的变量来存放每个选手的平均分,将平均分放进已经声明的float型的动态数组中 ,
(4)输出求出的平均值就是每个选手的最后得分,
(5)将float数组中的值进行冒泡排序再一次输出就是按从大到小的顺序输出五位选手的最后成绩。
问题1:
不能正确输出结果。
原因:
声明数组的时候没有实例化。
解决办法:
分别给两个数组分配了十和五的内存空间。
2.Email验证:在各种应用中,需要对用户输入的email地址进行验证,编写一个方法,判断一个email地址是否有效。(判断条件:A:@和.同时存在 B: @在.之前 C: 不能@开头 D: 以com|cn|net|gov|edu|org结尾 )
程序设计思路
(1)‘@’‘.’位置的判断,定义两个相同的方法,利用indexOf查找输入字符串中的字符并返回查找到的位置,
(2)定义一个方法利用startsWith判断输入的字符串是否以‘@’开头若是返回0,若不是返回1,
(3)定义一个后缀的判定方法:声明一个静态字符型数组,声明一个整型变量j赋值为0;截取输入的字符串从‘.’到最后一个,用循环的方式将截取的字符串和数组中的字符串一一比较若相同则j+1;若最后j==1则返回1否则返回0,
(4)主函数中声明一个String型变量并实例化,输入需要判定的邮箱,调用已经定义的方法,
if(a!=-1&&b!=-1&&a<b&&c==1&&d==1)
{
System.out.println("你输入的是一个正确的邮箱!");
}
else
{
System.out.println("你输入的是一个错误的邮箱!");
}
代码的意思是若可以查找到‘@’和‘.’且@在.之前且字符串不是以@开头并且以规定的后缀结尾则判定为正确邮箱,若有一项不符合就判定为错误邮箱。
问题1:
定义的方法名中存在错误。
原因:
方法返回类型和方法中返回值类型不同。
解决办法:
将方法返回类型和方法中返回值类型统一。
问题2:
最后一个后缀判断方法使用if else判断太过繁琐。
原因:
没有熟练掌握数组。
解决办法:
声明一个数组并用循环的方式进行比较即可简化。
问题3:
后缀判断方法中已经写出返回值却提示没有返回值。
原因:
返回值写在了在循环内。
解决办法:
将返回值移动到循环外写即可解决。
3.统计文件:输入一个字符串,包含各种文件类型的文件名。文件名之间用“,”分隔,要求将各个文件名的首字母大写后分别输出,并统计各种类型文件的文件个数。
程序设计思路:
(1)定义一个方法用split以‘,’为标志拆分,
(2)将方法1中拆分的字符串放入数组中,利用循环将数组中每个字符串的第一个字符截取并转为大写,再截取剩下的字符串与已经大写的字符拼接,
(3)输入字符串并调用定义的方法将拆分好并第一个字符大写的字符串存放到数组中并输出,
(4)用双重循环的方式截取字符串从‘.’开始到最后的内容并让当前截取出的内容与已经截取过的内容进行比较若出现一次相同则执行“n=0;n++”当n=1时将当前截取的字符串与每个完整的字符串执行endsWith判断完整的字符串是否以当前截取的字符串结尾,若是执行“m=0;m++”。m即为相同文件名的个数,若n>1则说明前面已经输出过相同文件名了,此时跳出循环程序结束。
问题1:
方法一存在错误。
原因:
返回值与方法返回类型不匹配。
解决办法:
返回值的类型为数组,方法返回类型为字符串,将方法返回类型改为字符型数组即可。
问题2:
相同文件名重复输出。
原因:
没有判定输出文件名是否重复。
解决办法:
加一个循环判定,在文件名已经出现过时跳出循环。
问题3:
加入循环判定后不能正常输出。
原因:
判断相等方法使用错误。
解决办法:
将循环判定字符串是否相等时将改为equal就可以解决,因为比较的是首地址,equal比较的是内容。
4.身份证识别:公民身份证号码由十八位数字组成。从左至右依次为:六位地址码,八位出生日期码,三位顺序码和一位校验码。顺序码的奇数分配给男性,偶数分配给女性。编写一个识别身份证基本信息的小工具,输入一个居民身份证号,则输出居民所属省份(直辖市、自治区),生日(格式:xxxx-xx-xx)和性别信息。
程序设计思路:
(1)将所有的地域名放入动态数组中同时放入第0行{}和第0“”列没有数据的部分方便后续判断,
(2)截取输入的字符串第一位位并将String利用Integer.parseInt转化为int型,
(3)截取输入的字符串第二位位并将String利用Integer.parseInt转化为int型,
(4)直接输出“place[j][x]”place为存放地域的数组,j为第一位,x为第二位,因为已经将数组中的空行和空列放入并且将字符转化为int型所以此时直接将j,x直接放入就可以正确输出居民所在地,
(5)截取输入的字符串第7-10位,11、12位,13、14位按xxxx-xx-xx格式输出就是居民生日,
(6)截取15-17位并转为int型和2求余若余数为0则输出为女性若为1则输出为男性,
问题1:
求余,数组地域判定等无法进行。
原因:
截取的字符串不是整型无法进行运算。
解决办法:
通过查阅资料掌握了Integer.parseInt方法将String转化为int型。
问题2:
无法正常输出地域。
原因:
数组中第0行0列有空值没有插入。
解决办法:
将数组中第0行第0列中的空值插入。
(三)代码托管(务必链接到你的项目)

代码托管:[https://git.oschina.net/ybyyy/shiyan22.git]
(四)学习进度
| ---------- | 代码行数(新增/累积) | 学习时间(新增/累积) | 本周学习内容 |
|---|---|---|---|
| 目标 | 8000行 | 400小时 | |
| 第2-4周 | 500/500 | 20/20 | 学习了 |
| 第5周 | 600/1100 | 40/60 | 学习了 |
| 第6周 |
浙公网安备 33010602011771号