实验一 Java编程环境使用
制作不易,点个关注!
第一关:String类的常用方法
任务描述
本关任务:阅读分析程序,按要求把程序中的代码补充完整,并查看结果。
相关知识
String类位于java.lang包下,是Java语言的核心类,提供了字符串的比较、查找、截取、大小写转换等操作。Java的String类包含了很多方法,下面介绍部分常用的方法,其它方法的使用请参看Java API文档。
1. public int length() 该方法用来获取一个String对象的字符序列的长度,例如:
1. String str = "String类的常用方法";
2. System.out.println(str.length());//输出12
3. System.out.println("我爱Java".length());//输出6
2. public boolean equals(Object anObject) 将当前String对象的字符序列与参数anObject指定的对象比较。例如:
1. String s1 = "AA";
2. String s2 = "AA";
3. System.out.println(s1.equals(s2)); // 输出true
4. System.out.println(s1 == s2); // 输出true
5. String s3 = new String("AA");
6. String s4 = new String("AA");
7. System.out.println(s3.equals(s4)); // 输出true
8. System.out.println(s3 == s4); // 输出false
String类重写了Object类的equals方法,比较的是String对象的字符序列内容是否相等,因此上述代码中,s1.equals(s2)和s3.equals(s4)比较都为true。由于字符串变量s1和s2所引用的字符串常量是保存在字符串常量池中,字符串常量池中不存在两个相同的对象,所以字符串变量s1和s2都是指向字符串常量池中的“AA”对象,对象的地址是相同的,因此s1 == s2为true。而字符串变量s3和s4是指向堆内存中两个不同的字符串对象,对象的地址是不同的,因此s3 == s4为false。
3. public int compareTo(String anotherString) 该方法是按字典顺序比较两个字符串对应字符的大小(ASCII码顺序),返回值是整型。如果两个字符串第一个字符不等,结束比较,返回他们之间的差值;如果两个字符串第一个字符相等,则进行第二个字符的比较,依次类推,直至比较的字符或被比较的字符有一方结束。 如果参数字符串等于此字符串,则返回值 0; 如果此字符串小于字符串参数,则返回一个小于 0 的值; 如果此字符串大于字符串参数,则返回一个大于 0 的值。 例如:
1. String str1 = "Strings";
2. String str2 = "Strings";
3. String str3 = "Strings123";
4. System.out.println(str1.compareTo(str2));//输出0
5. System.out.println(str2.compareTo(str3));//输出-3
6. System.out.println(str3.compareTo(str1));//输出3
4. public boolean contains(CharSequence s) 测试当前字符串对象的字符序列是否包含指定的字符序列,包含返回 true,否则返回 false。例如:
1. String str = "String类的常用方法";
2. System.out.println(str.contains("String"));//true
3. System.out.println(str.contains("string"));//false
5. public int indexOf(String str) 和 public int lastIndexOf(String str) 上面两个方法分别返回给定子字符串在当前字符串的字符序列中第一次和最后一次出现的索引位置,如果此字符串中没有这样的字符,则返回 -1。
注意:String对象的字符序列索引位置从0开始。 String对象的字符序列中转义字符是一个字符,例如,\n代表回车,如果要在字符序列中表示目录符号,那么Windows目录符必须转义写成\,Unix目录符直接写成/即可。例如:
1. String str = "String类的常用方法.java";
2. String path = "c:\\java\\jsp\\A.java";
3. System.out.println(str.indexOf("."));//输出12
4. System.out.println(path.indexOf("\\"));//输出2
5. System.out.println(path.lastIndexOf("\\"));//输出11
6. public boolean startsWith(String prefix) 和 public boolean endsWith(String suffix) 上面两个方法分别用来测试当前字符串是否以指定的前缀开始和以指定的后缀结束。例如:
1. String str = "String类的常用方法.java";
2. System.out.println(str.startsWith("java"));//false
3. System.out.println(str.endsWith("java"));//true
7. public String substring(int beginIndex) 该方法是从当前字符串的beginIndex索引处的字符开始,到字符串末尾结束,截取并返回一个新的字符串。另外,还可以使用重载的substring(int beginIndex, int endIndex)方法,截取并返回到指定索引 endIndex - 1 处的新的字符串。例如:
1. String str = "String类的常用方法.java";
2. int position = str.indexOf(".");
3. System.out.println(str.substring(position+1));//输出java
4. System.out.println(str.substring(0, 6));//输出String
8. public char[] toCharArray() 该方法是将当前字符串转换为一个新的字符数组。例如:
1. String str = new String("String类的常用方法");
2. char a[] = str.toCharArray();
3. for (int i = a.length - 1; i >= 0; i--) {
4. System.out.print(a[i] + " ");
5. }
运行结果: 法 方 用 常 的 类 g n i r t S
9. public String trim() 该方法返回字符串的副本,忽略前导空白和尾部空白。例如:
1. String str = " String类的常用方法 ";//字符串首尾带有空白字符
2. System.out.println(str.length());//输出14
3. System.out.println(str.trim().length());//输出12
编程要求
在Begin-End区域中按照要求补充代码。运行结果如下所示: s1与s2不相同 手机号以139开头 按字典序s4小于s5 d:\java\A.java中最后出现\的位置为: 7 d:\java\A.java中含有的文件名为: A.java 100 + 123.678 的和为: 223.678 数字223.678有3位小数 ABCDEF 逆序字符输出为: F E D C B A
测试说明
平台会对你编写的代码进行测试:若与预期输出相同,则算通关。
开始你的任务吧,祝你成功!
代码如下:
package step1;
public class StringExample {
public static void main(String args[]) {
String s1 = new String("you are a student");
String s2 = new String("how are you");
// 使用equals方法判断s1与s2是否相同
if ( s1.equals(s2) ) {
System.out.println("s1与s2相同");
} else {
System.out.println("s1与s2不相同");
}
String s3 = new String("13971918888");
// 判断手机号是否以“139”开头
if ( s3.startsWith("139") ) {
System.out.println("手机号以139开头");
}
String s4 = new String("你"), s5 = new String("我");
// 按着字典序s4大于s5的表达式
if ( s4.compareTo(s5)>0 ) {
System.out.println("按字典序s4大于s5");
} else {
System.out.println("按字典序s4小于s5");
}
/******************************************************/
int position = 0;
String path = "d:\\java\\A.java";
// 获取path中最后出现\\的位置
position = path.lastIndexOf("\\") ;
System.out.println(path + "中最后出现\\的位置为: " + position);
// 利用字符串截取方法获取path中“A.java”子字符串
String fileName = path.substring(position+1) ;
System.out.println(path + "中含有的文件名为: " + fileName);
/******************************************************/
String s6 = new String("100");
String s7 = new String("123.678");
// 将s6转化成int型数据
int n1 =Integer.parseInt(s6) ;
// 将s7转化成double型数据
double n2 =Double.parseDouble(s7) ;
double m = n1 + n2;
System.out.println(n1 + " + " + n2 + " 的和为: " + m);
// String类调用valuOf(double n)方法将m转化为字符串对象
String s8 = String.valueOf(m) ;
position = s8.indexOf(".");
// 利用字符串截取方法获取s8中小数点后面的小数
String temp = s8.substring(position+1) ;
System.out.println("数字" + m + "有" + temp.length() + "位小数");
String s9 = new String("ABCDEF");
// 将s9存放到数组a中
char a[] = s9.toCharArray() ;
System.out.print(s9 + " 逆序字符输出为: ");
for (int i = a.length - 1; i >= 0; i--) {
System.out.print(" " + a[i]);
}
}
}
第二关:矩阵转置
任务描述
本关任务:定义一个二维数组,并给二维数组赋值,分别打印原二维数组和行列互调后的二维数组。
相关知识
在实际考试中我们不止考试一门而是多门,那么多门考试的成绩我们需要用编程语言来处理时,我们怎么保存这些数据呢? 这就需要用到二维数组了。
二维数组
定义:二维数组是指以一维数组作为元素的数组。
语法:数据类型[行][列] 数组名。
二维数组的初始化
静态: 动态:
二维数组的使用
访问数组中的元素: 使用技巧:循环输出二维数组中的数据。 结果:
Scanner类的使用
使用 java.util.Scanner类 可将文本转换成原语或字符串。Scanner对象通过next()系列方法将文本标识转换成不同类型的值。
通常和标准输入流(System.in)结合,允许用户通过标准输入流读入数据。
Scanner类提供的方法:nextByte()、nextshort()、nextLong()、nextDouble()、nextFloat()、nextInt()等。例如:
1. Scanner scanner=new Scanner(System.in);
2. int i=scanner.netInt(); //从键盘输入一个整数
3. scanner.close(); //scanner对象用完后要关闭
编程要求
定义一个3行3列整型二维数组,并给二维数组赋值,分别打印出原二维数组和行列互调后的二维数组。
测试说明
平台会对你编写的代码进行测试:
测试输入: 1 2 3 4 5 6 7 8 9
预期输出:
原始数组为: 1 2 3 4 5 6 7 8 9 行列互调后数组为: 1 4 7 2 5 8 3 6 9
开始你的任务吧,祝你成功!
代码如下:
package step2;
import java.util.Scanner;
public class SwapMatrix {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int[][] matrix = new int[3][3];
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
matrix[i][j] = scanner.nextInt();
}
}
/********** Begin **********/
System.out.println("原始数组为:");
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
System.out.print(matrix[i][j]+" ");
}
System.out.println();
}
System.out.println("行列互调后数组为:");
int s=0;
for (int i = 0; i < 2; i++) {
for (int j = i; j < 3; j++) {
s= matrix[i][j];
matrix[i][j]=matrix[j][i];
matrix[j][i]=s;
}
}
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
System.out.print(matrix[i][j]+" ");
}
System.out.println();
}
/********** End **********/
scanner.close();
}
}
第三关:求平均分及各个区间段的人数
任务描述
本关任务:编写Java程序(Score.java),统计一批学生的成绩,求平均分及各个区间段的人数。
相关知识
为了完成本关任务,你需要掌握分支结构和循环结构的相关知识。
分支结构是根据给定条件确定后续语句执行流程的程序结构,主要用于描述程序中根据某些数据的取值或者计算结果选择不同的处理方式。Java提供了两种常见的分支控制结构:if语句和switch语句。
if 语句
if语句是专门用来实现分支结构的语句,它根据逻辑表达式的真假来进行分支控制。
1. 单分支if语句 单分支if语句的语法格式为:
1. if (逻辑表达式) {
2. 语句块;
3. }
单分支if语句执行过程如图1(a)所示:当逻辑表达式的值为真(true)时,则执行紧跟着的语句块;如果逻辑表达式的值为假(false)时,则执行if语句后面的其他语句。语句块如果只有一条语句,花括号{}可以省略不写,但为了增强程序的可读性最好不要省略。 图1 分支语句 【例1】将3个已知的整型数按升序排序输出。
4. public class Example1 {
5. public static void main(String[] args) {
6. int a=9, b=5, c=7, t;
7. if(a>b) {
8. t=a; a=b; b=t;
9. }
10. if(a>c) {
11. t=a; a=c; c=t;
12. }
13. if(b>c) {
14. t=b; b=c; c=t;
15. }
16. System.out.println("a="+a+",b="+b+",c="+c); // 输出a=5,b=7,c=9
17. }
18. }
运行结果: a=5,b=7,c=9
2. 双分支if语句 双分支if语句的语法格式为:
1. if (逻辑表达式) {
2. 语句块1;
3. } else {
4. 语句块2;
5. }
双分支if语句执行过程如图1(b)所示:当逻辑表达式的值为真(true)时,执行语句块1;如果表达式的值为假(false)时,则执行语句块2。if和else后面的语句块如果只有一条语句,花括号{}可以省略不写,但为了增强程序的可读性最好不要省略。另外,else子句不能作为语句单独使用,必须与if配对使用。 【例2】判断某年是否为闰年。闰年的判断条件是:年份能被4整除而不能被100整除,或者能被400整除。
6. public class Example2 {
7. public static void main(String[] args) {
8. int year = 2000;
9. boolean isLeapYear;
10. isLeapYear = (year%4==0 && year%100!=0)||(year%400==0);
11. if(isLeapYear) {
12. System.out.println(year + "年是闰年。");
13. } else {
14. System.out.println(year + "年不是闰年。");
15. }
16. }
17. }
运行结果: 2000年是闰年。
3. if 语句的嵌套 在单分支if语句和双分支if语句中,通过在分支中嵌套if语句,可以实现多分支选择结构的程序流程控制。if语句嵌套使用非常灵活,表1给出了一些常用if语句嵌套的例子,如果在下表中各分支继续嵌套if语句,可以实现更复杂的分支选择结构。 表1 常用if语句嵌套的例子
【例3】编写程序计算行李的托运费。行李托运费的计算方法为:行李重量不超过50公斤时,每公斤0.5元;超过50公斤不超过100公斤时,其超过部分每公斤1.5元;超过100公斤时,其超过部分每公斤2元。 分析:托运费的计算分三种情况: ① 当行李重量小于等于50公斤,托运费=0.5×行李重量。 ② 当行李重量大于50公斤小于等于100公斤,托运费=500.5+1.5×(行李重量-50)。 ③ 当行李重量大于100公斤,托运费=500.5+50*1.5+2×(行李重量-100)。
1. public class Example3 {
2. public static void main(String[] args) {
3. double weight = 90,money;
4. if (weight>50)
5. if(weight>100)
6. money=100+2*(weight-100);
7. else
8. money=25+1.5*(weight-50);
9. else
10. money=0.5*weight;
11. System.out.println("托运费:" + money + "元");
12. }
13. }
运行结果: 托运费:85.0元
switch语句
虽然if语句的嵌套形式能够实现多分支选择结构,满足程序流程控制的要求,但是嵌套层次越多,程序阅读、维护越困难。在Java中,为多路分支选择流程控制专门提供了switch语句,可以根据表达式的计算结果在多个分支中进行选择。switch语句的语法格式为: switch(表达式)
1. {
2. case 常量表达式1: 语句序列1;
3. case 常量表达式2: 语句序列2;
4. ……
5. case 常量表达式n: 语句序列n;
6. default : 语句序列n+1;
7. }
switch语句的执行过程是:首先计算充当选择角色的表达式的值,然后将该值依次与case后面的常量表达式的值进行比较;如果相等,则执行该常量表达式后面的语句,此时不再进行比较,继续执行后面所有case常量表达式后面的语句;如果表达式的值与所有常量表达式的值都不相等,则执行default后面的语句。 实际应用时,switch语句经常和break语句配合使用,以实现多分支选择程序流程控制。break语句是辅助流程控制语句,不能单独使用,必须和switch语句或循环语句一起使用。switch语句或循环语句执行时,遇到break语句,则switch语句或循环语句执行结束。例如:
1. switch(表达式)
2. {
3. case 常量表达式1: 语句序列1;break;
4. case 常量表达式2: 语句序列2; break;
5. case 常量表达式3: 语句序列3; break;
6. default : 语句序列4;
7. }
注意: ⑴ switch语句后面的控制表达式的数据类型只能是byte,short,int或char类型,case常量表达式的类型必须与表达式的类型相兼容。从Java SE 7开始,switch可以支持字符串String类型,case常量表达式必须是字符串常量或文字。 ⑵ 允许多个不同的case常量表达式运行一组相同的操作。例如: case 常量表达式1: case 常量表达式2: case 常量表达式3: 语句序列; break; … ⑶ 当case子句中包括多条运行语句时,无须用花括号{}括起来。 ⑷ break语句用来在运行完一个case分支后,将运行流程转向结构的出口,即结束switch语句,运行switch语句的后续语句。
循环结构也是流程控制结构之一,主要用于需要在指定条件下重复执行某些语句的场合。重复执行的条件被称为循环条件,通常用关系表达式或逻辑表达式表示,而重复执行的语句被称为循环体。Java的循环语句共有三种:while语句、do-while语句和for语句。在循环结构中还可以用continue语句和break语句来实现循环中流程特殊要求的转移。它们的执行流程结构如图3所示。 图3 Java的三种循环结构
while语句
while语句的语法格式如下:
1. while(循环条件){
2. 循环体;
3. }
while语句的执行过程如图3(a)所示。该语句执行的过程为:首先,判断循环条件的值,如果其值为真,就执行循环体,循环体执行完之后再无条件转向循环条件进行计算与判断;当计算出循环条件为假时,跳过循环体执行while语句的后续语句。
注意:在循环体中,一般要包含改变循环条件表达式的语句,否则会造成无限循环(死循环)。
【例4】用while语句求1+2+3+…+100的和。
1. public class Example4 {
2. public static void main(String[] args) {
3. int i=1, sum=0;
4. while(i<=100) {
5. sum = sum + i;
6. i++;
7. }
8. System.out.println("sum=" + sum);
9. }
10. }
运行结果: sum=5050
do-while语句
对于while语句而言,如果不满足条件,则不能进入循环。但有时候我们需要即使不满足条件,也至少执行一次,则可以使用do-while语句。do-while语句的语法格式如下:
1. do{
2. 循环体;
3. }while(循环条件);
do-while语句的流程结构如图3(b)所示。该语句执行的过程为:先执行循环体语句,后判断循环条件的值。如果循环条件的值为真,继续执行循环体;如果循环条件的值为假,则结束循环。
do-while语句和while语句都是实现循环结构,但两者是有区别的:do-while语句先执行循环体,然后判断循环条件的值,再决定是否进行循环;而while语句是先判断循环条件的值,再决定是否执行循环体。所以用do-while语句时,循环体至少执行一次。
注意:与while语句一样,在do-while的循环体中,也要包含改变循环条件表达式的语句,否则会造成无限循环(死循环)。另外,while语句后面的分号不要漏掉。
【例5】用do-while语句求1+2+3+…+100的和。
1. public class Example5 {
2. public static void main(String[] args) {
3. int i=1, sum=0;
4. do {
5. sum = sum + i;
6. i++;
7. } while(i<=100);
8. System.out.println("sum=" + sum);
9. }
10. }
运行结果: sum=5050
for语句
for语句的语法格式如下:
1. for(表达式1;表达式2;表达式3){
2. 循环体;
3. }
for语句的流程结构如图3©所示。每个for语句都有一个用来决定循环开始和结束的变量,通常这个变量称为循环控制变量。表达式1用来给循环控制变量赋初值,它只在进入循环的时候执行一次。表达式2是一个关系或逻辑表达式,是循环进行的条件,若其值为真,则运行循环体内容;否则结束循环,程序流程转向循环结构出口,运行for语句的后续语句。表达式3用于改变循环控制变量的值。三个表达式之间用分号分隔。
另外,Java语言也允许在表达式1和表达式3的位置上包含多条语句。for语句的运行顺序如下:
(1) 首先计算表达式1的值,完成必要的初始化工作。 (2) 判断表达式2的值。若其值为真执行循环体内容,然后运行第(3)步;若其值为假则结束循环,转到第(5)步。 (3) 求解表达式3。 (4) 回到第(2)步继续运行。 (5) 运行for语句的后续语句。 【例6】用for语句求1+2+3+…+100的和。
1. public class Example6 {
2. public static void main(String[] args) {
3. int sum=0;
4. for(int i=1;i<=100;i++) {
5. sum+=i;
6. }
7. System.out.println("sum=" + sum);
8. }
9. }
运行结果: sum=5050
while循环和for循环是可以互换的;通常情况下,如果知道循环的次数的话,使用for循环;不知道循环次数时,使用while循环,也可以使用for循环。
循环嵌套与continue、break语句
在循环体内又包含另外一个完整的循环结构,称为循环嵌套。内嵌的循环中还可以再次嵌套循环形成多重循环。while循环、do-while循环和for循环都可以相互嵌套使用。 Java语言没有提供goto语句来控制程序的跳转,这种做法提高了程序流程控制的可读性,但降低了程序流程控制的灵活性。为了弥补这种不足,Java提供了continue和break语句来控制循环结构。 1. break语句
有时候需要在某种条件出现时强行终止循环,而不是等到循环条件为假时才退出循环。此时,可以使用break语句来完成此功能。break语句除可以在循环语句中使用外,还可以用于switch 语句中。
【例7】用break语句求1+2+3+…+100的和。
1. public class Example7 {
2. public static void main(String[] args) {
3. int sum = 0;
4. for (int i = 1;; i++) {
5. sum = sum + i;
6. if (i == 100) {
7. break;
8. }
9. }
10. System.out.println("sum=" + sum);
11. }
12. }
运行结果: sum=5050
使用for循环计算从1到100时,我们并没有在for()中设置循环退出的检测条件。但是,在循环体内部,我们用if语句判断,如果i==100,就通过break语句退出循环。
因此,break语句通常都是配合if语句使用的。要特别注意,break语句总是跳出自己所在的那一层循环。
【例8】两层循环嵌套中break应用示例。
1. public class Example8 {
2. public static void main(String[] args) {
3. for (int i = 1; i <= 10; i++) {
4. for (int j = 1; j <= 10; j++) {
5. System.out.println("j = " + j);
6. if (j >= i) {
7. break;
8. }
9. }
10. // break跳到这里
11. System.out.println("breaked");
12. }
13. }
14. }
运行结果:
1. j = 1
2. breaked
3. j = 1
4. j = 2
5. breaked
6. ……
上面的代码是两层for循环嵌套。因为break语句位于内层的for循环,因此,它会跳出内层for循环,但不会跳出外层for循环。
2. continue语句
break语句会跳出当前循环,也就是整个循环都不会执行了。而continue则是提前结束本次循环,直接继续执行下次循环。 【例9】用continue语句实现打印10以内的奇数。
1. public class Example9 {
2. public static void main(String[] args) {
3. for (int i = 1; i <= 10; i++) {
4. if (i % 2 == 0) {
5. continue;
6. }
7. System.out.print(i + " ");
8. }
9. }
10. }
运行结果: 1 3 5 7 9
上面代码中,当i能被2整除时,利用continue语句结束本次循环,不再执行输出i值的代码,而是继续执行下次循环。
编程要求
这是一个计数和累加问题。学生数量不确定,但有一个结束标记(-1),该问题的总体结构是一个循环处理问题,可用while循环,当输入数据为-1时结束循环。为了统计各种情况的人数,需要设立相应的计数变量,并给其赋初值0,另外为了求平均分,必须计算总分,也就是计算出所有学生成绩的累加和,然后除以总人数即可得到平均分。
注意:平均分结果保留1位小数。
测试说明
平台会对你编写的代码进行测试:
输入数据样例: 75.5 80 92.5 64.5 55 87.5 98 -1 输出结果样例: 不及格的人数为:1 及格的人数为:1 中等的人数为:1 良好的人数为:2 优秀的人数为:2 全班平均分为:79.0
开始你的任务吧,祝你成功!
代码如下:
package step3;
import java.util.Scanner;
public class Score {
public static void main(String args[]) {
Scanner scanner = new Scanner(System.in);
/********** Begin **********/
int failCount = 0, passCount = 0, mediumCount = 0, goodCount = 0, excellentCount = 0;
double totalScore = 0;
double score = scanner.nextDouble();
int studentCount = 0;
while (score != -1) {
studentCount++;
totalScore += score;
if (score < 60) {
failCount++;
} else if (score < 70) {
passCount++;
} else if (score < 80) {
mediumCount++;
} else if (score < 90) {
goodCount++;
} else {
excellentCount++;
}
score = scanner.nextDouble();
}
double averageScore = totalScore / studentCount;
averageScore = Math.round(averageScore * 10.0) / 10.0;
System.out.println("不及格的人数为:" + failCount);
System.out.println("及格的人数为:" + passCount);
System.out.println("中等的人数为:" + mediumCount);
System.out.println("良好的人数为:" + goodCount);
System.out.println("优秀的人数为:" + excellentCount);
System.out.println("全班平均分为:" + averageScore);
/********** End **********/
scanner.close();
}
}