《Java技术》第XX次作业
(一)学习总结
1.学习使用Eclipse关联jdk源代码,查看String类的equals()方法,截图,并学习其实现方法。举例说明equals方法和==的区别。
equals方法截图:
equals方法的源码如下:
public boolean equals(Object obj)
{
if(this == obj)
return true;
if(obj instanceof String){
String s = (String)obj;
int i = value.length;
if(i == s.value.length){
char ac[] = value;
char ac1[] = s.value;
for(int j = 0; i-- != 0; j++)
if(ac[j] != ac1[j])
return false;
return true;
}
}
return false;
}
从代码可以看出如果是同一个对象的地址,该方法就直接返回true,若不是同一个对象的地址进行比较就逐个比较字符是否相等。若是相同就返回true,否则返回false。在基本数据类型中short,char,int,long,float,double等,它们用 == 比较,比较的是值,而复合数据类型(String等),比较的是对象的内存地址。
2.什么是构造方法?什么是构造方法的重载?
构造方法是一个与类同名且没有返回值类型的方法。对象的创建就是通过构造方法来完成,它的功能主要是完成对象的初始化。当类实例化一个对象时会自动调用构造方法。
构造方法的重载则是在创建对象时,系统会自动根据所调用的构造方法中包含的参数类型,个数,选择匹配的构造方法创建对象。
下面的程序是否可以通过编译?为什么?
public class Test {
public static void main(String args[]) {
Foo obj = new Foo();
}
}
class Foo{
int value;
public Foo(int intValue){
value = intValue;
}
}
不能通过编译,因为没有在有参构造方法中传递一个参数,应在Foo obj = new Foo()中添加一个参数,如:Foo obj = new Foo(10); ,可通过编译。
3.运行下列程序,结果是什么?查阅资料,分析为什么。
public class Test {
public static void main(String args[]) {
double a = 0.1;
double b = 0.1;
double c = 0.1;
if((a + b + c) == 0.3){
System.out.println("等于0.3");
}else {
System.out.println("不等于0.3");
}
}
}
结果是不等于0.3,尝试输出a+b+c的值,如下图:
因为浮点运算很少是精确的,只要是超过精度能表示的范围就会产生误差。往往产生误差不是 因为数的大小,而是因为数的精度。因此,产生的结果接近但不等于想要的结果。修改如下:
import java.math.BigDecimal;
public class Test {
public static void main(String args[]) {
add();
}
public static void add(){
BigDecimal a1 = new BigDecimal ("0.1");
BigDecimal b1 = new BigDecimal ("0.1");
BigDecimal c1 = new BigDecimal ("0.1");
System.out.println(a1.add(b1).add(c1).doubleValue());
if(a1.add(b1).add(c1).doubleValue()==0.3){
System.out.println("等于0.3");
}
else {
System.out.println("不等于0.3");
}
}
}
4.运行下列程序,结果是什么?分析原因,应如何修改.
public class Test {
public static void main(String[] args) {
MyClass[] arr=new MyClass[3];
arr[1].value=100;
}
}
class MyClass{
public int value=1;
}
不能按照数组的方式来一下定义多个对象,会出现赋值失败。
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类,为什么?性能有差异吗?能否写出测试代码证明你的结论。(可查阅资料)
当拼接次数多的时候,使用String方法会消耗大量的性能和时间,因为每次String拼接时都会建立一个新的对象,随着拼接次数的增多,性能消耗、时间消耗会大量增加,这个时候应该使用StringBuffer方法。
public class test {
public static void main(String[] args) {
String cc = "chengyifei";
long t1=System.currentTimeMillis();
for(int i=0;i<10000;i++){
cc = cc + "chengyifei";
}
long t2=System.currentTimeMillis();
System.out.println((t2-t1)/1000f); //string类的用时
StringBuffer aa = new StringBuffer();
long t3=System.currentTimeMillis();
for(int i=0;i<10000;i++){
aa.append("chengyifei");
}
long t4=System.currentTimeMillis();
System.out.println((t4-t3)/1000f); //stringbuffer类的用时
}
}
用以上代码运行的结果是:
显然用StringBuffer类耗时更少,性能更好。
(二)实验总结
1.评分系统
- 程序设计思路:
定义一个长度为10的数组,通过五次循环,为每次选手的十次分数赋值,每次循环中,先求最大值,最小值,再将分数总和减去最大值最小值除以8得出平均分,存到另一个数组中,最后将平均分排序倒序输出。 - 实验问题分析:
问题:无法输出平均分。
原因:平均分为double类型,总分,最大值与最小值均为为int型。
解决方案:
for(int x=0;x<score.length;x++){
sum = sum+(double)score[x];
}
max = (double)max(score);
min = (double)min(score);
将整数型 强制转换成double型
2.email有效地址验证
- 程序设计思路:
将用户输入的邮箱字符串,传递到我的判断方法中,分别用startWith,endWith,indexof来判断是否符合规则。 - 暂无问题
3.字符串统计
- 程序设计思路:
首先将输入的字符串,按照“,”分隔开存放到一个字符串数组s[]中,再把每个独立字符串中的“.”后面的字符串存放到另一个字符串数组p[]中,将s[]字符串数组中的每个字符串第一位分隔开换成大写再与后续相连接,再分别输出可以将每个文件名输出,用三个循环嵌套,统计p[]中重复出现的字符串则是对文件类型的统计,后续输出。 - 实验问题分析:
问题:对最后输出的xx类型的文件有xx个,数量统计不正确。
原因:p[]数组中即使比较过的字符串也会重复比较
解决方案:设置第三个循环,如果遇到已经出现过的文件名则跳出循环。
4.身份证识别
- 程序设计思路:
把输入的身份证号字符串分成三个部分,利用三个方法,来判断地址,性别,出生年月,省市可以用二维字符串数组来存放 - 实验问题分析:
问题:程序不能正常执行,地址不能正常输出
原因:数组长度越界
解决方案:将原有的add[6][7],改成add[7][8],增加了长度。