Java第二次作业——数组和String类


学习总结

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



步骤为窗口->首选项->已安装的jre;双击jre7标准vm,找到rt.jar将安装目录中存在src.zip的路径添加进去,完成操作。


代码如下:

public class Test1 extends Test {
	public static void main(String[] args) {
		String str1="hello";
		String str2="hello";
		String str3=new String("hello");
			System.out.println("堆内存里存储的hello相等"+(str1==str2));
			System.out.println("字符串的内容相等"+str1.equals(str2));
			System.out.println("字符串的内容相等"+str1.equals(str3));
			System.out.println("堆内存里存储的不相等"+(str1==str3));
	}
}

equals比较的是字符串的内容,而str1==str2比较的是内存里存储的。共同点都是返回boolean类型,相等则返回true,不相等则返回false


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

构造方法条件:1,必须跟类名相同。2,不能有返回值。3,在构造函数声明处没有返回值类型的声明

构造方法的重载:在主函数中调用构造方法,相当于调用函数,只不过是用类声明了的。并且一个类可以有多个构造方法,系统有默认的构造方法,所以没有写也会自动补上。

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(0);也可以在类的定义构造方法里更改:

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

去掉形参,然后在class Foo程序里面添加变量intValue,并赋初值。

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。



会发现出现3.300000000000003这个数字,原因是精度不够。float和double只能用来做科学计算或者是工程计算,在商业计算中我们要java.math.BigDecimal。所以java中就有了BigDecimal这个类,可以精确准度。使用如下:

import java.math.BigDecimal;
public class Test1 {
	    public static void main(String args[]) { 
	        double a = 0.1;
	        double b = 0.1;
	        double c = 0.1;
	        if(Math.round(Math.add(a, b, c), 1) == 0.3){      //四舍五入的调用  
	            System.out.println("等于0.3");
	        }else {
	            System.out.println("不等于0.3");
	        }
	    }     
	}
class Math{
	public static double add(double a1,double a2,double a3){  //三个数的相加
		BigDecimal b1=new BigDecimal(a1);
		BigDecimal b2=new BigDecimal(a2);
		BigDecimal b3=new BigDecimal(a3);
		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();
	}
}

更改后的程序如下:


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;
}

错误的原因是:调用数组对象为空,没有赋初值,没有分配内存空间的方法。


正确的方法为:为arr分配堆空间。如下

	 public class Test1 {
	    public static void main(String[] args) {
	    	 MyClass[] arr={new MyClass(),new MyClass(),new MyClass()};
	    	 arr[0].value=2;
	    	 System.out.println(arr[0].value); 
	    }
	    }
	    class MyClass{
	    public int value=1;
	    }


5.在一个10000次的循环中,需要进行字符串的连接操作,那么,应该使用String类还是StringBuffer类,为什么?性能有差异吗?能否写出测试代码证明你的结论。(可查阅资料)
  public class Test1 {
public static void main(String[] args) {
	String str1="chenyameng";
	for(int i=0;i<100;i++){
		str1=str1+i;
	}
	System.out.println(str1);
}
  }

在应对大量的数据处理是应当使用StringBuffer类,在使用String类的时候改变的是堆内存的指向,在堆内存改变的时候需要断开然后在进行链接,这样的操作导致效率很低。

使用StringBuffer类的代码如下:

public class Test1 {
    public static void main(String[] args) {
    	StringBuffer str1=new StringBuffer();
    	buf.append("chenyameng");
    	for(int i=0;i<1000000;i++){
    		buf.append(i);
    	}
    	System.out.println(buf);
    	
    }
  }

使用StringBuffer类使字符串变为可变的,所以其字符串可以随意连接,效率更快。


实验总结

实验内容:

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

程序设计思路:二维数组定义,外循环为评委的人数,内循环控制的是每个评委给的分数

int score[][]=null;
score = new int [5][10];
for(int i=0;i<score.length;i++){
			System.out.println("请输入第"+(i+1)+"个人的分数:");
			for(int j=0;j<score[i].length;j++){
				int a=in.nextInt();
				score[i][j]= a ;
			}
		}

编写方法来找到二维数组中的最大值和最小值,需要注意的是方法必须返回一个值来表示是哪个评委的分数。否则总会出现最近的一个数组。

	public static int min(int p,int imin[][]){
	int min = imin[p][0];
		for(int j=0;j<imin[p].length;j++){
			if(imin[p][j]<min)
			{
				min=imin[p][j];
			}	
		}
	return min;	
}

然后在求平均数中调用min和max函数求每行的和,然后再减去max,min,最后除8或者该数组.length。

		public static float avg(int p,int iscore[][]){
				float sum=0;
					for(int j=0;j<iscore[p].length;j++){
						sum+=iscore[p][j];
					}
				sum=sum-max(p,iscore)-min(p,iscore);
				return sum/8;
			}

最后创建一个数组,然后把avg返回来的值给了该数组,排序即可完成操作。

float isort[]=null;
		isort=new float[5];
		for(int i=0;i<isort.length;i++){             //shuzu
			isort[i]=avg(i,score);
		}
		Arrays.sort(isort);
		System.out.println("排序后的数组为:");
		for(int i=0;i<isort.length;i++){
	        System.out.print(isort[i]+"\t");
	    }

倘若用一维数组,则需要用for循环来控制人数:

	for(int i=1;i<3;i++){
				System.out.println("请输入第"+i+"选手的成绩:");
				for(int j=0;j<score.length;j++){
					int a=in.nextInt();
					score[j]= a ;
				}
				for(int j=0;j<score.length;j++){
					System.out.print(score[j]+"\t");
				}
				System.out.println("\t");
				System.out.println("第"+(i)+"位选手的最高分为:"+max(score));
				System.out.println("第"+(i)+"位选手的最低分为:"+min(score));
				System.out.println("第"+(i)+"位选手的平均分为:"+avg(i,score));	
				}

然后同样把avg函数返回来的数字返回给数组。在调用排序函数完成操作。

仍然存在待解决的问题:在一维数组中,返回数组出现错误,总是将最后输出的avg输出来。


2.Email验证:在各种应用中,需要对用户输入的email地址进行验证,编写一个方法,判断一个email地址是否有效。(判断条件:A:@和.同时存在 B: @在.之前 C: 不能@开头 D: 以com|cn|net|gov|edu|org结尾 )

程序设计思路:用while控制输入输出,然后用if来判断字符串是否符合要求即可。

问题1:判断总是输入错误

原因:在if判断语句中

if((!s.startsWith("@"))&&((s.endsWith("com"))||(s.endsWith("cn"))||(s.endsWith("net"))||(s.endsWith("gov"))||(s.endsWith("edu"))||(s.endsWith("org")))
&&(s.indexOf("@")!=-1)&&(s.indexOf(".")!=-1)&&((s.indexOf("@"))<(s.indexOf("."))))

com和cn,net等没有分开写,直接写成了s.endsWIth(“com||cn||net”)这种格式。

问题2:在编写判断的方法中无法使用break,所以直接在main函数中直接编写,没有编写方法。

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

程序设计思路:先将字符串以“,“分割放入一个数组中

	String si[]=null;
		si=new String[10];
		String []ssi=null;   /* 定义一个数组然后将输入的字符串分割放入si数组中*/
		si=s.split("\\,");
		ssi=s.split("\\,|\\.");
		for(int i=0;i<si.length;i++){
			System.out.println(si[i]);
		}	

然后在以.分割放入一个数组中并输出ssi=s.split("\\,|\\.")

for(int i=0;i<ssi.length;i++){
			System.out.println("ssi[i]"+i+ssi[i]);			
		}

判断ssi[i]数组中的奇数项就是文件名后缀,然后再放入一个数组ssssi[]中

int j=0;
		for(int i=0;i<ssi.length;i++){
				if(i%2==1){	
					ssssi[j]=ssi[i];j++;
					
				}	  //chen.txt,yang.java,fei.doc,hui.pptx,ya.java			
			}

然后设置一个标志数组,数组内全部为1,int biaoben[]={1,1,1,1,1,1,1,1,1,1};
然后ssssi[]数组中进行比较相同的后缀名,如果相同则biaoben数组加1;
问题1:不会比较

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

程序设计思路:定义一个二维数组来定义省份的前两个数字,过程中需要用到Integer.parseInt这个类进行将字符串转换为int型,substring类来截取相应的字符来进行判断。同样使用while来控制循环,用多层的if嵌套来判断,用if来判断条件是否符合,例如:

    if(sn.length()>18){
				System.out.println("输入错误,请重新输入");
			}
			else{

判断长度是否输入正确,错误则重新输入。
if((im>0&&im<12)&&ia<32)来判断天数是否输入正确。都输入正确则输出省份等信息。

这次的学习,更加地了解了String类,和数组的定义,在定义的过程中需要用到new来开辟空间,在数组中需要注意的是不要出现越界问题。多查找jdk帮助文档来使用多种方法,例如这次身份证识别中的Integer.parseInt方法。

代码托管


程序在ex-02文件中

 posted on 2017-03-28 15:40  ben跑的换行符  阅读(474)  评论(0编辑  收藏  举报