《Java技术》第二次作业

(一)学习总结

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

==是用来数值比较的,比较的是地址,而equals比较的是内容。

==比较:

equals方法比较字符串:

2.什么是构造方法?什么是构造方法的重载?下面的程序是否可以通过编译?为什么?
构造方法是指方法名称与类名一样的,声明处不能有任何返回值类型声明,没有return返回一个值。
构造方法的重载是指每个方法的参数类型或者参数个数不同。
不可以通过编译,因为Foo中有一个参数,而调用的时候没有参数。所以编译错误。
修改:在调用的时候加一个参数如“1”

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

3.运行下列程序,结果是什么?查阅资料,分析为什么。为了处理精度损失的问题,可以使用java.math.BigDecimal类,查阅JDK帮助文档或教材p378,对上述程序进行修改。
程序运行结果是0. 30000000000000004
因为double和float是对不需要任何计算精确的数字才适用。
修改后的程序:

    import java.math.BigDecimal;
    public class Test {
        public static void main(String args[]) { 
                double a = 0.1;
                double b = 0.1;
                double c = 0.1;
                double d = add(a,b,c);
             if(round(d,1)== 0.3){
                      System.out.println("等于0.3");
             }
          else {
               System.out.println("不等于0.3");
             }
         }
    public static double add(double a1,double b1,double c1){
                 BigDecimal a=new BigDecimal(a1);
                 BigDecimal b=new BigDecimal(b1);
                 BigDecimal c=new BigDecimal(c1);
                 return a.add(b).add(c).doubleValue();
    }
    public static double round(double d,int len){
                 BigDecimal d1=new BigDecimal(d);
                 BigDecimal d2=new BigDecimal(1);
                 return d1.divide(d2,len,BigDecimal.ROUND_HALF_UP).doubleValue();
        }
    }

4.运行下列程序,结果是什么?分析原因,应如何修改.
结果是:

    Exception in thread "main" java.lang.NullPointerException
        	at Text.main(Text.java:4)

原因:主方法为static方法,而从class不是static,所以不能在text里对MyClass进行访问。

    public class Text {
         public static void main(String[] args) {
                 MyClass[] arr = new MyClass[3];
                 arr[1].value = 100;
                 System.out.println(arr[1].value);
         }
    }
    class MyClass {
         public static int value = 1;
    }

5.在一个10000次的循环中,需要进行字符串的连接操作,那么,应该使用String类还是StringBuffer类,为什么?性能有差异吗?能否写出测试代码证明你的结论。(可查阅资料)
String类的内容一旦声明就不可以改变,而StringBuffer类可以改变。
StringBuffer类可以直接利用循环连接(append方法可以连续调用,该方法只是在原地址上进行连接,省空间)。

      public class Text {
         public static void main(String[] args) {
         StringBuffer str = new StringBuffer("Hello word!");
         for (int i = 0; i < 10000; i++) {
                 str.append("@.@");
         }
       System.out.println(str);
    }

6.其他需要总结的内容。
写程序太拖沓,没有办法完全离开书本,犯重复错误(把声明瞎放),写程序前最好把思路写下来,循环的嵌套也写出来,这样思路比较清楚,不用写一点再重新理一遍。

(二)实验总结

1.评分系统:一共10个评委,满分10分,假设有5个选手,分别由评委打分,去掉一个最高分和一个最低分后的平均分为该选手得分,将选手的得分从高到低进行输出。

  • 程序设计思路:先定义了找最大值、最小值、平均数三个方法,从main中调用,再利用循环将每位选手的最后成绩存入另外一个数组,再定义一个排序方法将存有最后成绩的数组排序,最后在main调用并输出。

    public static int max(int a[]);
    public static int min(int a[]);
    public static float avg(float sum);
    public static void paixu(float w[]);

  • 实验问题分析:
    问题1:定义存入选手最后成绩的数组总是为空值
    原因:将数组的声明放到了for循环里面,导致每循环一次,数组重新定义一次。
    解决方案:将w[]声明放在for循环外面,在循环里面把avg给w[]

     float w[]=new float[5];
     for(int j=0;j<5;j++){
     	float sum=0;
     	System.out.println("请输入评委为第"+(j+1)+"位选手打的分数:");
     	for(int i=0;i<a.length;i++){
     		int score = in.nextInt();
     		a[i]=score;
     		System.out.println("第"+(i+1)+"位评委的分数是"+"  "+a[i]);
     		sum=sum+a[i];
     	}
     	sum=sum-max(a)-min(a);
     	System.out.println("选手最终得分为"+avg(sum));
     	w[j]=avg(sum);
     }
    

    问题2:按从大到小输出成绩,总是把最大的成绩输出五次
    原因:定义排序方法,用冒泡排序将数组内数据排序,在main中输出
    解决方案:

    public static void paixu(float w[]){
    for(int k=1;k<w.length;k++){
    for(int j=0;j<w.length;j++){
    if(w[k]>w[j]){
    float max=w[k];
    w[k]=w[j];
    w[j]=max;
    }
    }
    }
    }
    2.在各种应用中,需要对用户输入的email地址进行验证,编写一个方法,判断一个email地址是否有效。(判断条件:A:@和.同时存在 B: @在.之前 C: 不能@开头 D: 以com|cn|net|gov|edu|org结尾 ) 在main方法中对该方法进行测试。

  • 程序设计思路: 根据题目中的ABCD,写了三个方法(BC在同一个方法中,只需要让@的下标不等于0并且小于“.“的下标),并在main中调用

    public static int tongshi(String str);
    public static int zhiqian(String str);
    public static int jiewei(String str);

  • 实验问题分析:
    问题1: 无法确定是否以cn结尾
    原因: 直接截取三个字符串,cn前还有一个字符,进行比较时一定不一样。
    解决方案:分开截取

    String str2=str.substring(a-3);
    String str9=str.substring(a-2);

3.输入一个字符串,包含各种文件类型的文件名。文件名之间用“,”分隔,要求将各个文件名的首字母大写后分别输出,并统计各种类型文件的文件个数。

  • 程序设计思路: 先用str.split(",")将字符串分开,存入数组,再用str5.split("\.")将文件夹类型找出来,再用循环求个数

  • 实验问题分析:
    问题1:不能以”.”进行分割
    原因: 用\.,上课讲过,用的时候就不知道怎么用。
    解决方案:String s[]=str5.split("\.");

    问题2: 无法统计文件个数
    原因: 循环嵌套出问题,第一题的错误重复出现,将声明放在循环里面,每循环一次就重新声明一次。
    解决方案: 求助同学,重新理了一下循环嵌套,将声明进行修改

     for (int i = 0; i < w.length; i++) {
     	int k = 1;
     	for (int m = 0; m < w.length; m++) {
     		if (w[m] != null) {
     			for (int j = m + 1; j < w.length; j++) {
     				if (w[m].equals(w[j])) {
     					k++;
     					w[j] = null;
     				}
     			}
     		}
     	}
     	n[i] = k;
     }
    

4.公民身份证号码由十八位数字组成。从左至右依次为:六位地址码,八位出生日期码,三位顺序码和一位校验码。顺序码的奇数分配给男性,偶数分配给女性。
编写一个识别身份证基本信息的小工具,输入一个居民身份证号,则输出居民所属省份(直辖市、自治区),生日(格式:xxxx-xx-xx)和性别信息。

  • 程序设计思路: 将18位身份证码,分成三部分,一部分是地址码,一部分是生日,还有一部分是性别,然后写两个方法,一个是判断籍贯,一个是判断性别。

         public static String dizhi(String str);
         public static String sex(String str);
    
  • 实验问题分析:
    问题1:利用二维数组输出籍贯时,会出现重复。
    原因: 没有及时跳出for循环
    解决方案:加一个if语句,施加约束

         for(int i=0;i<dw.length;i++){
     	    for(int j=0;j<dw.length;j++){
     	            	if(i==a&&j==b){
     		            	str=dw[i][j];
     	            	}
     	    }
         }
    

(三)[代码托管] https://git.oschina.net/hebau_cs15/cs01wmx.git

码云commit历史截图

(四)学习进度条

代码行数(新增/累积) 学习时间(新增/累积) 本周学习内容
目标 8000行 4000小时
第2-4周 400/400 40/40 学习了自己写的代码中的知识点,看了一些课外的程序
第5周 400/ 400 35/35 在课上讲的String类用法,温习了很多遍,写程序的时候也查了不少资料,对各种类型做了总结。
第6周