java第二次作业 李新磊

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

(一)学习总结

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

Eclipse关联jdk源代码,查看String类的equals()方法

(1)"窗口">"首选项">"Java">"已安装的JRE".

(2)此时"已安装的JRE"右边是列表窗格,列出了系统中的JRE环境,选择本地的JRE,然后左边的 "编辑", 出现窗口"编辑 JRE"

(3)选中rt.jar文件中的 c:\program files\java\jre_1.5.0_06\lib\rt.jar; 点左边的+号展开,可以看到:源代码链接:无,选择这一项,点右边的按钮源代码附件, 选择JDK目录下的 src.zip文件

(4) 查看equals()方法

equals() 方法与"=="的区别

==比较的是2个对象的地址,而equals比较的是2个对象的内容

    String str1="absalom"; 
    String str2=",absalom!"; 
    String str3="absalom,absalom!"; 
    String str4="absalom,absalom!"; 
     
    Boolean b1=(st1==st2); 
    Boolean b2=(st1+st2)==st3; 
    Boolean b3=(st3==st4); 
     
    System.out.println("str1==str2 比较结果:"+b1);
    System.out.println("(str1+str2)==st3 比较结果:"+b2);
    System.out.println("str3==str4 比较结果:"+b3); 

//对象变量存储的是对象的内存地址。用“==”比较时,两个对象的值相等,但内存地址不同,所以==的结果为false。

    Boolean r1=str1.equals(str2); 
    Boolean r2=(str1+st2).equals(str3); 
    Boolean r3=str3.equals(str4); 
     
    System.out.println("str1.equals(st2) 比较结果:"+r1);
    System.out.println("(str1+str2).equals(str3) 比较结果:"+r2);
    System.out.println("st3.equals(str4) 比较结果:"+r3); 

//equal比较两个对象内容是否相同 
} 

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定义为为value赋值,调用时需要参数。

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

精度丢失
0.1 无法准确地表示为float与double类型
例如,float的0.1二进制形式是001111011 10011001100110011001101,根据符号位换算为10进制表达的值,应为 110011001100110011001101乘以2的负27次方,实际值是0.100000001490116119384765625
这样就产生了实际误差

import java.math.BigDecimal;
public class test {
public static void main(String args[]) { 
	          BigDecimal a = new BigDecimal ("0.1");
	          BigDecimal b = new BigDecimal ("0.1");
	          BigDecimal c = new BigDecimal ("0.1");	 
	          if(a.add(b).add(c).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{new MyClass(),new MyClass(),new MyClass()};
    arr[1].value=100;
}
}
class MyClass{
    public int value=1;
}

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

应使用StringBuffer类。

String类表示的字符串是常量,创建后内容和长度不能改变;StringBuffer类表示字符容器,内容和长度可以随时修改。
String方法会消耗大量的性能和时间,因为每次String拼接时都会建立一个新的对象,随着连接次数的增加,性能消耗会显著增加,所以应使用StringBuilder方法。

//使用String类
public class test {
	    public static void main(String args[]) {
	        String str =new String("absalom");
	        for (int i=0; i<10000;i++) {
	            str =  str+",absalom!";
	        }
	         System.out.println(str);
	    }
   }   
//使用StringBuffer类
import java.lang.StringBuilder;
public class test {
    public static void main(String args[]) { 
    	StringBuffer str=new StringBuffer("absalom");
    	for(int i=0;i<10000;i++){
    		str.append=(",absalom!");
    	}
    	System.out.println(str);
     }        
 }

(二)实验总结

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

程序设计思路

(1)定义得分数组score[10]和最终得分数组mark[5],存储每个选手的得分和最终得分。

                for(int i=0;i<5;i++){
			int score[]=new int[10];
			System.out.printf("请10位评委输入%d号选手得分\n",i+1);
			for(int j=0;j<10;j++){
			score[j]=in.nextInt();
			}
			marks[i]=avgScore(score);/*5位选手的最终得分存入数组marks中*/
		}

(2)定义求最高分、最低分、最终得分方法int maxScore(int score[]) ,int minScore(int score[]) ,double avgScore(int score[]),计算最终得分。

(3)将5个成绩降序排序输出

问题1:如何计算每个选手的最终得分

public static double avgScore(int score[]){
		int sum=0;double avg=0.0;
		for(int j=0;j<10;j++){
				sum+=score[j];/*求10个得分的和*/
			}
		avg=(double)(sum-minScore(score)-maxScore(score))/8.0;/*去掉最高分最低分,求最终得分*/
		return avg;
	}

问题2:如何将5个成绩降序排序输出

运用数组排序方法Arrays.sort(),将最终得分数组升序,再从尾到头输出(降序)。

Arrays.sort(marks);
		System.out.println("分数由高到低输出");
		for(int k=4;k>=0;k--){
		System.out.printf("%.2f\n",marks[k]);
		}

2.Email验证:在各种应用中,需要对用户输入的email地址进行验证,编写一个方法,判断一个email地址是否有效。

程序设计思路

(1)编写一个判断方法judgeMent(String email),运用indexOf判断 @ 和 . 是否存在,如存在,判断 @ 的位置是否在 . 前;运用email.endsWith()判断结尾是否为com|cn|net|gov|edu|org
(2)编写一个测试方法

public static void test(){
		String test1="absalom@.com",test2="absalom.@com",test3="@absalom@.com",test4="absalom@.uuu";/*测试邮箱*/
		System.out.println("\n测试1:absalom@.com");
		if(judgeMent(test1))
			System.out.println("yes");
		else
			System.out.println("no");
		System.out.println("测试2:absalom.@com");
		if(judgeMent(test2))
			System.out.println("yes");
		else
			System.out.println("no");
		System.out.println("测试3:@absalom@.com");
		if(judgeMent(test3))
			System.out.println("yes");
		else
			System.out.println("no");
		System.out.println("测试4:absalom@.uuu");
		if(judgeMent(test4))
			System.out.println("yes");
		else
			System.out.println("no");
		
	}

问题1.如何实现判断

(判断条件:A:@和.同时存在 B: @在.之前 C: 不能@开头 D: 以com|cn|net|gov|edu|org结尾 )
运用indexOf判断 @ 和 . 是否存在,如果indexOf("@")值为-1,说明不存在;
如存在,判断 @ 的位置是否在 . 前,indexOf("@")的值是否小于indexOf(".");
运用email.endsWith()判断结尾是否为com|cn|net|gov|edu|org

public static boolean judgeMent(String email){
		
		if(email.indexOf("@")!=-1&&email.indexOf(".")!=-1&&email.indexOf("@")<email.indexOf(".")&&email.indexOf("@")!=0){/*如果indexOf("@")值为-1,说明不存在;如果indexOf("@")值为1,说明@开头;如果indexOf("@")的值小于indexOf("."),说明 @ 在 . 的前面*/
			if (email.endsWith("com")){
				return true;
				}
			else if(email.endsWith("cn")){          /*endWith()判断是否以指定字符串结尾*/
				return true;
			}
			else if(email.endsWith("net")){
				return true;
			}
			else if(email.endsWith("gov")){
				return true;
			}
			else if(email.endsWith("edu")){
				return true;
			}
			else if(email.endsWith("org")){
				return true;
			}
			else {
				return false;
			}
			
				}	
			else {
				return false;
			}
	}

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

程序设计思路

(1)编写一个字符串拆分方法toSplit(String str),以 ,为界拆分并存储到字符串数组中,输出文件名。

public static void toSplit(String str){
		String s[]=str.split(",");/*拆分后的文件名储存到字符串数组中*/
		for(int i=0;i<s.length;i++){	
			System.out.println(s[i]);		/*循环输出*/
		}
		
	}

(2)编写一个统计文件类型及其个数的方法addUp(String str),将字符串以 ,为界拆分为文件名,储存到字符串数组extension中,再将每个文件名以 . 为界拆分为扩展名,存储到extension中,这样extension数组存储的是扩展名而不是文件名,再将数组元素依次两两比较,统计每种类型的文件名个数。

问题1.如何实现首字母大写输出

将字符串拆分为文件名,存储到字符串数组中,将数组中每个元素转换为字符数组,再将第一个元素(首字母)转换为大写。

public static void toSplit(String str){
		String s[]=str.split(",");
		for(int i=0;i<s.length;i++){
			char c[]=s[i].toCharArray();
			for(int j=0;j<c.length;j++){
                                if(c[0]>='a'){
				    c[0]-=32;/*如果首字母为小写,则ASCLL值减32*/
				}
			System.out.print(c[j]);	
			}	
			System.out.printf("\n");
		}
		
	}

问题2.如何统计文件类型及其个数

将字符串以' ,'为界拆分为文件名,储存到字符串数组extension中,再将每个文件名以' . '为界拆分为扩展名,存储到extension中,这样extension数组存储的是扩展名而不是文件名,再将数组元素依次两两比较,统计每种类型的文件名个数。

  • 将第一个类型名与之后所有类型名比较,统计第一个类型名的个数,再执行统计第二个类型名,先将第二个类型名与前一个类型名比较,如果相同,代表已经统计过,将此类型名替换为空;如果不同,继续将这个类型名与之后的所有类型名比较,以此类推,每统计一个元素,都和之前的所有元素比较,确保不统计重复。
public static void addUp(String str){
			String[] extension=null;/*定义字符串数组,存储文件名*/
			extension=str.split(",");/*以,为界,按照文件名拆分为多个字符串*/
			for(int a=0;a<extension.length;a++){
				extension[a]=extension[a].substring(extension[a].indexOf(".")+1);/*从.的位置开始到数组的最后,截取文件扩展名,字符串数组内存储扩展名*/
			}
			int k=1;/*某类型文件个数*/
			for(int m=0;m<extension.length;m++){
					for(int n=m+1;n<extension.length;n++){
						if(extension[n].equals(extension[m]))/*依次两两比较,计算该类型文件个数*/
						{
							k++;
						}
						for(int i=0;i<n;i++){					/*比较当前元素与之前所有的元素是否相同,如果相同,代表这个类型的文件已经被统计过*/
							if(extension[n].equals(extension[i])){  /*如果被统计过,将这个类型名替换为空*/
								extension[n]=" ";
							}
						}
					}
					if(!extension[m].equals(" "))
						System.out.println(extension[m]+"文件: "+k);
						k=1;
			}
					
		}	

4.身份证识别:公民身份证号码由十八位数字组成。从左至右依次为:六位地址码,八位出生日期码,三位顺序码和一位校验码。顺序码的奇数分配给男性,偶数分配给女性。

编写一个识别身份证基本信息的小工具,输入一个居民身份证号,则输出居民所属省份(直辖市、自治区),生日(格式:xxxx-xx-xx)和性别信息。

程序设计思路

(1)将各省份存储到一个二维字符串数组province[][]中,这样各省份的编号与数组下标+1对应。

String province[][]= {{"北京市","天津市","河北省","山西省","内蒙古"},
							  {"辽宁省","吉林省","黑龙江省"},
							  {"上海市","江苏省","浙江省","安徽省","福建省","江西省","山东省"},
							  {"河南省","湖北省","湖南省","广东省","广西","海南省"},
							  {"重庆市","四川省","贵州省","云南省","西藏"},
							  {"陕西省","甘肃省","青海省","宁夏","新疆"}};

(2)编写一个获取省份的方法getAddress(String id),读取id的前两位,判断数字-1与下标对应的关系。
(3)编写一个获取出生日期的方法getBirth(String id),读取id的6-14位,输出。
(4)编写一个获取性别的方法getSex(String id),读取id的17位,判断奇数偶数。

问题1.如何获取省份信息

运用包装类Integer,读取id的前两位,将其转换为Integer型,作为数组下标,再进行输出。

public static void getAddress(String id){
		String province[][]= {{"北京市","天津市","河北省","山西省","内蒙古"},
							  {"辽宁省","吉林省","黑龙江省"},
							  {"上海市","江苏省","浙江省","安徽省","福建省","江西省","山东省"},
							  {"河南省","湖北省","湖南省","广东省","广西","海南省"},
							  {"重庆市","四川省","贵州省","云南省","西藏"},
							  {"陕西省","甘肃省","青海省","宁夏","新疆"}};
		String  getprovince1=id.substring(0,1);
		String  getprovince2=id.substring(1,2);
		Integer i=Integer.valueOf(getprovince1);
		Integer j=Integer.valueOf(getprovince2);
		System.out.println("籍贯 "+province[i-1][j-1]);
		
	}

问题2.如何获取性别信息

运用包装类Integer,读取id的前17位,将其转换为Integer型,判断奇偶。

public static void getSex(String id){
		String  getsex=id.substring(16,17);
		Integer sex=Integer.valueOf(getsex);
		if(sex%2==0)
			System.out.println("性别 女");
		else
			System.out.println("性别 男");	
	}

(三)代码托管

https://git.oschina.net/hebau_cs15/Java-CS02lxl/tree/master/ex02?dir=1&filepath=ex02&oid=b11e8d99d2ec283d7602c60c44d69b52aef2551d&sha=cfda4988ef2790c9dccf34b963c159a471c76eca

posted on 2017-03-25 09:33  押沙龙  阅读(434)  评论(2)    收藏  举报