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文件中