java:编写一个学生管理程序,选择集合类存储学生的学号、姓名和期末考试各科的成绩(课程名+成绩,假设只包括数学、语文和英语三门课程)。实现如下功能:

(一)实验类型:设计性

(二)实验目的:

1. 掌握Java语言的集合类;

2. 掌握程序调试的常用方法,培养良好的Java编程习惯。

(三)实验内容:

1. 编写一个学生管理程序,选择集合类存储学生的学号、姓名和期末考试各科的成绩(课程名+成绩,假设只包括数学、语文和英语三门课程)。实现如下功能:

(1)学生信息(学号+姓名)录入;

(2)学生成绩录入(课程+得分);

(3)根据姓名查找学号。

(4)根据学号查找姓名。

(5)根据学号查找成绩。

(6)根据学号和课程名查找学生的成绩。

(7)根据学号计算平均分,并屏幕输出。

(8)根据平均分对班级学生成绩排序,按从高到低的顺序输出姓名和平均成绩。


import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;

class Stu
{	
	private String id;
	private String name;
	private String classChe,classMath,classEng;//课程名
	private int che,math,eng;//成绩 
		
	public Stu(String id,String name,
			String classChe,String classMath,String classEng,int che,int math,int eng)
	{
		this.id=id;
		this.name=name;
		this.classChe=classChe;
		this.classMath=classMath;
		this.classEng=classEng;
		this.che=che;
		this.math=math;
		this.eng=eng;
		
		
	}//构造方法直接插入数据
	//构造方法不需要写类型!因为不需要返回值
	
	//创建set就是为了存储数据到类中,get就是为了得到单个变量的值
	//如果用了重载类储存数据也可不写set,更简洁。
	//因为class是动态的,不是静态就不能直接stu[i].che这样获取值
	//必须要写一个函数如get实现return来获取值
		
		
		public String getId(){
			return id;
		}
		
	    public String getName(){
			return name;
		}

			
		public int getEng(){
			return eng;
		}
		
		public int getMath(){
			return math;
		}
		
		public int getChe(){
			return che;
		}

		public String getClassEng(){
			return classEng;
		}
		
		public String getClassMath(){
			return classMath;
		}
		
		public String getClassChe(){
			return classChe;
		}
		
	
		public String find1(String name,int len,Stu[] stu)
		//写方法的时候表明是对象数组即可
		{
	    	for (int i = 0; i < len; i++)
	    	   if (stu[i].getName().equals(name)) 
	    		   return stu[i].id;
	    	//将类中存放的名字与传入的名字比对
	    	//找到相同名字时就将对象中的学号返回,
	    	//后面同理
	    	return null;//java中必须要有明确的返回值
	} 

		
		public String find2(String id,int len,Stu[] stu)
		{
	    	for (int i = 0; i < len; i++)
	    	   if (stu[i].getId().equals(id)) 
	    		   return stu[i].name;
	    
	    	return null;
	} 
		
		public int find3(String id,int len,Stu[] stu){
	    	for (int i = 0; i < len; i++)
	    	   if (stu[i].getId().equals(id))
	    		   return i;
	    	return -1;
	} 

		public int find4(String classname,int len,Stu[] stu){
			
	    	for (int i = 0; i < len; i++)
	    	   if (stu[i].getClassChe().equals(classname)||stu[i].getClassMath().equals(classname)||stu[i].getClassEng().equals(classname))
	    		   return i;
	    	return -1;
	} 
		
		public int ave(int a,int b,int c)
		{
			return (a+b+c)/3;
		}
		
	}

class R
{
	public String name;
	public int ave;
	
	
	
	public R(String name,int ave)
	{
		this.name=name;
		this.ave=ave;
	}
	
	public int getAve()
	{
		return ave;
	}
	
	public String getName()
	{
		return name;
	}
}



public class StudentManagementProcedure{
	public static void main(String args[])
		{
		Scanner in=new Scanner(System.in);
		int n=in.nextInt();//插入学生个数
		
		Stu[] stu = new Stu[n];//创建数组
		for(int i=0;i<n;i++)
		{
		    stu[i]=new Stu(in.next(),in.next(),in.next(),in.next(),in.next(),in.nextInt(),in.nextInt(),in.nextInt());//分配空间
		}
		
		//只设置一次查找先,需要查找多少次可以自己设置
		
		
		//根据姓名查找学号。
		
			
			String name=in.next();
			String id=stu[0].find1(name,n,stu);//这里随便用一个学生的find即可 
			System.out.println(id);
			//传参的时候只用把数组的名字传上去就行了
		
	
		//根据学号查找姓名。
		
			id=in.next();
			 name=stu[0].find2(id,n,stu);
			System.out.println(name);

		
		
	//根据学号查找成绩。
		
			 id=in.next();
			int key=stu[0].find3(id,n,stu);//成绩有三个
			//为了方便输出结果,我们换成获取下标。
			System.out.println("语文数学英语"+stu[key].getChe()+" "+stu[key].getMath()+" "+stu[key].getEng());
			
			
			
			//根据课程名查找学生的成绩。
			 String className=in.next();
			  key=stu[0].find4(className,n,stu);//成绩有三个
			//为了方便输出结果,我们换成获取下标。
			System.out.println("语文数学英语"+stu[key].getChe()+" "+stu[key].getMath()+" "+stu[key].getEng());
			
		 // int[] rank=new int[n];err 因为要存放两个量,所以不能只开一个整型数组
		  //其实java的class在存放变量的性质就跟结构体是一样的
		  //多个变量就要开一个类来包装使用
		
			
			
//根据学号计算平均分,并屏幕输出。
			id=in.next();
			 key=stu[0].find3(id,n,stu);
		    int val=stu[key].ave(stu[key].getChe(),stu[key].getMath(), stu[key].getEng());
		 //平均分也是要几个成绩,所以获取下标
		    //本质上也是根据学号获取下标,可以复用前面的方法
			System.out.println(val);
			
			//根据平均分对班级学生成绩排序,按从高到低的顺序输出姓名和平均成绩。
		R[] rank=new R[n];
			
			for(int i=0;i<n;i++)
			{
			  
			     val=stu[i].ave(stu[i].getChe(),stu[i].getMath(), stu[i].getEng());
			    rank[i]=new R(stu[i].getName(),val);///申请空间+重载赋值
			    
			}
			
			//java只有升序,且降序输出比较困难,所以干脆就先升序排序然后降序输出
			//Collections.sort(rank, (p1, p2) -> ((R) p2).getAve()-((R) p1).getAve()); err
			//比对了很多方法,发现插入到列表中再排序是最方便简洁的
			
		   List<R>rankList=new ArrayList<>();
		   for(int i=0;i<n;i++)
			   rankList.add(rank[i]);
		   
		   Collections.sort(rankList,(p1,p2)->p2.getAve()-p1.getAve());
		   //              排序对象   选定先后元素  从哪里-哪里,-就相当于从..到..的意思
		   
		  
		   for(R r:rankList)
			 //R是元素类型,r是元素/一个对象,rankList指循环中的所有对象  
			   //元素的名字可以任意取
			   {
			   //System.out.println(r);  // err
			   //直接写元素为什么不行见
			   //https://blog.csdn.net/ASBSIHD/article/details/131018839?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22131018839%22%2C%22source%22%3A%22ASBSIHD%22%7D
			   System.out.println(r.getName()+" "+r.getAve());
			   
		   }
		 
		   
//		   for (int i = 0; i < rankList.size(); i++) {
//		    System.out.println(rankList.get(i));
//		}//获取到列表的下标就能直接输出其结果
//		//常规输出方法示例
		   

		//知识: for (type variable : collection) {
				    // code block to be executed
				}

				    
				//其中,type表示要遍历集合中的元素类型,variable表示一个临时变量,
	//用于存储集合中每个元素的值,collection表示要遍历的集合对象。
	
	
	//代码可以改进,都改为获取下标,只要是根据的数据不变
			//都是可以复用方法的!
			//没有必要开这么多个方法
			

	
	//测试样例
//1
//1314
//Amiya
//chinese
//math
//english
//80
//88
//95
//Amiya
//1314
//1314
//math 
//1314
	
	//行吧,eclipse本身的问题,可能我的这个样例的编排有问题。或者这么长的数据
	//本身就数据量太大了,一次输出不完,所以要再次回车才能输出完全
	      
	        
		
		
		
	
			
		}