项目需求
1.学生成绩查询系统中保存学生姓名、课程名称以及学生的课程成绩。
2.查询系统从控制台输入统计命令以及参数,实现成绩的查询。主要命令如下:
avg Java:统计课程Java的平均分。
avg song:统计学生song的平均分。
get song Java:获取学生song的Java课程的成绩。
sort Java:列出Java课程的成绩排序结果。
exit:退出程序。
如果查询的学生或课程不存在时,给出相应的提示。运行结果如图所示。
2.项目开发步骤与内容
查询系统的数据结构:
1.将学生的课程成绩保存在一个二维数组中,每一行表示一个学生的成绩,每一列表示每一门课的成绩。
2.将每门课的名称保留在一个一维数组中,且课程的下标序号与二维数组的列号匹配。
3.将每个学生的名字保留在一个一维数组中,且学生是下标序号与二维数组的行号匹配。
学生数和课程数用常量的方式存储:
final int STUDENR_NUM=6;
final int COURSE_NUM=5;
学生的名字和课程的名称分别存在一维数组中:
static String[] students={"zhang","wang","li","zhao","liu","song"};
static String[] courses={"C","Java","mySQL","Linux","HTML"};
学生成绩存在二维数组中:
static int[][] score=new int[STUDENR_NUM][COURSE_NUM];
初始化数组,输出数组即显示成绩,执行查询系统的控制台命令调度。
3.代码实现
程序主体
先把程序主体写出来,引用出待会需要用到的类,把题给的常量敲上去,方法待会慢慢补充。
import java.util.Arrays;
import java.util.Scanner;
public class ProjectTraining4{
static final int STUDENR_NUM=6;
static final int COURSE_NUM=5;
static String[] students={"zhang","wang","li","zhao","liu","song"};
static String[] courses={"C","Java","mySQL","Linux","HTML"};
static int[][] score=new int[STUDENR_NUM][COURSE_NUM];
public static void main(String[] args){
chuShiHua();//初始化
show();//成绩展示
control();//指令控制
}
static void chushihua(){...}
static void show(){...}
static void control(){...}
static void avg(...){...}
static void get(...){...}
static void sort(...){...}
static void exit(){...}
}
b.数据的初始化
把题给的学生成绩对应的数组元素。
static void chuShiHua(){//初始化
score[0]=new int[]{26,69,46,25,5};//zhang
score[1]=new int[]{27,10,24,66,58};//wang
score[2]=new int[]{44,58,0,82,75};//li
score[3]=new int[]{6,68,92,9,84};//zhao
score[4]=new int[]{75,1,51,41,74};//liu
score[5]=new int[]{23,38,65,1,55};//song
}
c.学生成绩展示
把学生名、课程名和对应的成绩用for循环输出成表格,最好用printf格式化输出,算好格子。不然行与行、列与列之间对不齐就不美观了。
static void show(){//成绩展示
System.out.print("\t");
for (String i: courses) {
System.out.printf("%-8s",i);//格式化输出
}
for(int i=0;i<students.length;i++){
System.out.printf("\n%-5s",students[i]);//格式化输出
for(int j=0;j<score[0].length;j++){
System.out.print("\t"+score[i][j]);
}
}
}
c.指令控制台
这是整个程序的关键。主体结构就是while循环,一旦检测到exit的输入就调用exit方法并跳出循环。
这里字符串的输入用到了.next()方法和.nextLine()方法,它们的区别我的理解是:".next()"是读取键盘输入并转成字符串但它并不接受空格(所以遇到空格就自动结束读取);".nextLine()"根据它的命名应该是读取这一行的所有东西并转成字符串,可以接受空格,输入也可以为空。
由于".nextLine()"方法的读取方式导致object2的第一个字符永远是空格(当然前提是不为空),虽然这只是一点小小的瑕疵,无伤大雅。但是,秉承着程序员(目前还不是)严谨、细心的美德,在查阅了别的大神的一些文章,查到了"str.trim()"方法可以去除字符串首尾的空格(该方法只是能去除首尾的)。
然后就是简单的if选择语句调用相对应的方法,因为字符串不能用"=="来进行判断,所以这里用到"str.equal()"方法。
static void control(){
Scanner in=new Scanner(System.in);
while (true){
System.out.print("\n请输入命令:");
String order=in.next();//字符串输入,遇到空格结束
if(order.equals("exit")){
exit();
break;
}
String object1=in.next();//
String object2=in.nextLine();//输入可以为空
object2=object2.trim();//str.trim()可以去除字符串首尾空格
//System.out.println(object1);//测试
//System.out.println(object2);//测试
if(order.equals("avg")){
avg(object1);
}else if(order.equals("get")){
get(object1,object2);
}else if(order.equals("sort")){
sort(object1);
}
}
}
d.求平均值avg
这里没什么技术含量,以我目前的水平就是力大砖飞了。唯一的一点就是"str.equalsIgnoreCase()"方法是不区分大小写的字符串判断,因为输入的命令一般都是小写的,但课程名中有大写的字母。
static void avg(String object1){
//System.out.println("测试,进入avg指令");
double sum=0;
double avgs=0;
int cout=1;
//不区分大小写的字符串比较:equalsIgnoreCase
if(object1.equalsIgnoreCase("C")){
for(int i=0;i<students.length;i++){
sum=sum+score[i][0];
}
avgs=sum/6.0;
}else if(object1.equalsIgnoreCase("Java")){
for(int i=0;i<students.length;i++){
sum=sum+score[i][1];
}
avgs=sum/6.0;
}else if(object1.equalsIgnoreCase("mySQL")){
for(int i=0;i<students.length;i++){
sum=sum+score[i][2];
}
avgs=sum/6.0;
}else if(object1.equalsIgnoreCase("Linux")){
for(int i=0;i<students.length;i++){
sum=sum+score[i][3];
}
avgs=sum/6.0;
}else if(object1.equalsIgnoreCase("HTML")){
for(int i=0;i<students.length;i++){
sum=sum+score[i][4];
}
avgs=sum/6.0;
}else if(object1.equals("zhang")){
for(int i=0;i<courses.length;i++){
sum=sum+score[0][i];
}
avgs=sum/5.0;
}else if(object1.equals("wang")){
for(int i=0;i<courses.length;i++){
sum=sum+score[1][i];
}
avgs=sum/5.0;
}else if(object1.equals("li")){
for(int i=0;i<courses.length;i++){
sum=sum+score[2][i];
}
avgs=sum/5.0;
}else if(object1.equals("zhao")){
for(int i=0;i<courses.length;i++){
sum=sum+score[3][i];
}
avgs=sum/5.0;
}else if(object1.equals("liu")){
for(int i=0;i<courses.length;i++){
sum=sum+score[4][i];
}
avgs=sum/5.0;
}else if(object1.equals("song")){
for(int i=0;i<courses.length;i++){
sum=sum+score[5][i];
}
avgs=sum/5.0;
}else{
cout=0;
System.out.print("你输入的既不是课程名,也不是学生名");
}
if(cout==1)System.out.printf("%s的平均分是:%.2f",object1,avgs);//保留两位小数,java自动四舍五入
}
e.获取某个学生的某门课程的成绩get
这里也是简单的if语句,记录学生、课程所对应的二维数组的下标,最后输出就行。
static void get(String object1, String object2){
int i=-1;
int j=-1;
if(object1.equals("zhang")) i=0;
else if(object1.equals("wang")) i=1;
else if(object1.equals("li")) i=2;
else if(object1.equals("zhao")) i=3;
else if(object1.equals("liu")) i=4;
else if(object1.equals("song")) i=5;
else System.out.print("没有"+object1+"这个人");
if(i!=-1){
if(object2.equalsIgnoreCase("C")) j=0;
else if(object2.equalsIgnoreCase("Java")) j=1;
else if(object2.equalsIgnoreCase("mySQL")) j=2;
else if(object2.equalsIgnoreCase("Linux")) j=3;
else if(object2.equalsIgnoreCase("HTML")) j=4;
else System.out.print(object1+"没有"+object2+"这门课程");
if(j!=-1) System.out.print(object1+"的"+object2+"的成绩是:"+score[i][j]);
}
}
f.成绩排序sort
这里也是力大砖飞,"Arrays.sort()"方法可以对数组从小到大进行排列(书上有),注意输出格式,要输出一个整齐的排名表。
static void sort(String object1){
int i=-1;
if(object1.equalsIgnoreCase("C")) i=0;
else if(object1.equalsIgnoreCase("Java")) i=1;
else if(object1.equalsIgnoreCase("mySQL")) i=2;
else if(object1.equalsIgnoreCase("Linux")) i=3;
else if(object1.equalsIgnoreCase("HTML")) i=4;
else System.out.print("没有这门课程");
if(i!=-1){
int[] chengji=new int[6];
for(int j=0;j<students.length;j++){
chengji[j]=score[j][i];
}
int[] nameindex=new int[6];
Arrays.sort(chengji);
for(int a=0;a<students.length;a++){
for(int b=0;b<students.length;b++){
if(score[b][i]==chengji[a]){
nameindex[a]=b;
break;
}
}
}//寻找各个成绩所对应的名字的下标
System.out.print("名次\t姓名\t"+object1);
for(int k=0;k<students.length;k++){
System.out.println();
System.out.printf("%-8d%-8s%-8d",k+1,students[nameindex[k]],chengji[k]);
}
}
}
g.退出程序exit
static void exit(){
System.out.println("退出查询系统!byebye!");//over
}
h.编译运行
功能完善,界面整洁。
4.总结
通过这个项目实训了解了Java的一些方法,比如".next()" ".nextLine()" "str,trim()"等,不过我还是觉得我写的这个代码的结构并不美观甚至是跟坨翔一样,主要原因应该是代码的阅读量太少了。
最后,有不对的地方欢迎指正。