JAVA实验二

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

1.1.String类的equals()方法

public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String) anObject;
        int n = value.length;
        if (n == anotherString.value.length) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            while (n-- != 0) {
                if (v1[i] != v2[i])
                        return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

1.2."" 用来进行数值的比较,而"equals"比较的是内容
”的方法

public class String1{
    public static void main(String[] args){
    String str1='hello';
    String str2=new String("hello");
    System.out.println("str1==str2->"(str1==str2));
}

运行结果:

str1==str2->false

equals 方法

 public class String2{
        public static void main(String[] args){
        String str1='hello';
        String str2=new String("hello");
        System.out.println("str1 equals str2->"(str1.equals(str2)));
    }

运行结果:

str1 equals str2->ture

---虽然俩种方法在堆内存中所存的的内容都是"hello",但是对于str1和str2来说,它们的地址的值不同,所以用"=="得到的是结果是false而equals得到的是true。

2.什么是构造方法?什么是构造方法的重载?下面的程序是否可以通过编译?为什么?

---构造方法就和C语言中的构造函数差不多,可以在主方法中直接调用。构造方法的名称必须和类名称一致且没有返回值。方法的重载就是方法名称相同,但参数的类型和参数的个数不同,通过传递参数的个数及类型不同以完成不同功能的方法调用。

public class Test {
    public static void main(String args[]) { 
    Foo obj = new Foo();       
    }
}
class Foo{
    int value;
    public Foo(int intValue){
        value = intValue;
     }
}

---不能通过编译,在Foo类中定义int型的value,而在主方法中Foo obj = new Foo()没有传递参数。

3.运行下列程序,结果是什么?查阅资料,分析为什么。

运行结果为:
不等于0.3
原因:
---double精度高,0.1转化为二进制为0.0001100110011...,将其放入double中为0.00011001100110011001100110011001100110011001100110011010,在进行double类型的数值运算时,会把一些没必要的数字给忽略,造成结果不对。
修改:
---要想准确计算精度的数字,必须使用BigDecimal类,不能用double和float.

class Math{
    public static double add(double a,double b,double c){
	    BigDecimal b1=new BigDecimal(a);
	    BigDecimal b2=new BigDecimal(b);
	    BigDecimal b3=new BigDecimal(c);
	    return b1.add(b2).add(b3).doubleValue();
    }
    public static double round(double d,int len){
    	BigDecimal b1=new BigDecimal(d);
	    BigDecimal b2=new BigDecimal(len);
	    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 b1=Math.round(Math.add(a, b, c),1);
	        if(b1 == 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();
        arr.value=100;
    }
}
class MyClass{
    public int value=1;
}

5.在一个10000次的循环中,需要进行字符串的连接操作,那么,应该使用String类还是StringBuffer类,为什么?性能有差异吗?能否写出测试代码证明你的结论。(可查阅资料)

---应该使用StringBuffer类。Stringlei的特性是String的内容一旦声明则不可改变,如果改变,则改变的是Stringd的引用地址。在这个10000次的循环中,字符串要经常改变,必须使用StringBuffer类,使用String类就会感到效率不高。
---注意:String类中可以用"+"进行字符串的连接,而StringBuffer类中只能使用append()方法进行字符串的连接。

String类

 public class Test {
    public static void main(String[] args) {
        String str = new String("hello");
        long start=System.currentTimeMillis();
        for(int i=1;i<10000;i++){
	        str+=i;
        }
    System.out.println(str);
    System.out.println(System.currentTimeMillis()-start);
    }
}

运行结果:

StringBuffer类

public class Test {
    public static void main(String[] args) {
        StringBuffer buf = new StringBuffer ();
        buf.append("hello");
        long start=System.currentTimeMillis();
        for(int i=1;i<10000;i++){
	        buf.append(i); 
        }
    System.out.println(buf);
    System.out.println(System.currentTimeMillis()-start);
    }
}

运行结果:

---明显使用StringBuffer类比String类效率高。
通过查找String类和StringBuffer类的区别得到System.currentTimeMillis()的功能是产生一个当前的毫秒,通过它来有效的比较俩种类的效率。

6.其他总结
---通过对以上程序的修改,可以学到更过有关JAVA的内容,包括字符串的连接,double类型精准度的丢失问题,比较效率的问题等等,这更加丰富了我的知识,是我对JAVA的学习更深了一步。

(二)实验总结
---1.评分系统:一共10个评委,满分10分,假设有5个选手,分别由评委打分,去掉一个最高分和一个最低分后的平均分为该选手得分,将选手的得分从高到低进行输出。定义适当的方法。
程序设计思路:共10个评委,首先需要定义一个数组来存放评委所打的分数,然后判断最大值和最小值(假设第一个是最大值,往后的依次与它进行比较,如果大于第一个,则输出该值为最大值,同理最小值一样),去除最大值与最小值求其平均分。共计5位选手,加个循环即可。之后将选手的得分从高到低进行输出。
问题1:将选手的得分没有输出
原因:所求得得分未放入数组中
解决方案:每次循环就把一个得到的得分放入一个新的数组中即可

    double[] score1=new double[5];
	for(int j=0;j<5;j++){
		for(i=0;i<score.length;i++){
			System.out.println("评委评分为:");
			score[i]=in.nextInt();
		}
		min=max=score[0];
		for(i=0;i<score.length;i++){
			if(score[i]>max){
				max=score[i];
			}
			if(score[i]<min){
				min=score[i];
			}
		sum=score[i]+sum;
		arv=(sum-max-min)/8;
		}
			score1[j]=arv;
			System.out.println("最高分为"+max);
			System.out.println("最低分为"+min);
			System.out.println("最后得分为"+arv);
	}

问题2:将选手的得分没有按从高到低输出
原因: for循环是顺序输出的
解决方案:
---改为逆序输出

        ...
        paixu();
		for(int j=4;j>=0;j--){
			System.out.println(score1[j]);
		}
		...

---2.Email验证:在各种应用中,需要对用户输入的email地址进行验证,编写一个方法,判断一个email地址是否有效。(判断条件:A:@和.同时存在 B: @在.之前 C: 不能@开头 D: 以com|cn|net|gov|edu|org结尾 )
程序设计思路:输入一个字符串,用indexOf方法,startsWith方法以及endsWith方法进行判断即可。
问题:编写该程序一开始想到的是用数组形式来表示,感觉有点繁琐,就没用,而用的是String类中indexOf方法,startsWith方法以及endsWith方法,感觉更简单。

(三)代码托管

(四)学习进度

---- 代码行数(新增/累积) 学习时间(新增/累积) 本周学习内容
目标 5000行 300小时
第2-4周 300/300 30/30 学习了Java
第5周 150/200 25/25 学习了精准度问题,字符串连接效率等等
第6周
https://git.oschina.net/hebau_cs15/java_CS01wfy.git
posted @ 2017-03-27 12:35  不羁的青春  阅读(175)  评论(0编辑  收藏  举报