前言:
第七次题目集共有四道题目。其中有两道考察HashMap的检索与排序功能,一道考察多态的运用,最重要的一道是成绩计算系统-2。
第八次题目集共有五道题目,考察了ArrayList容器的排序方法、身份证排序方法、自定义接口、覆盖等知识,还有成绩计算系统-3。该系统是成绩计算系统-2的升级版,修改了类结构,将成绩类的继承关系改为组合关系,成绩信息由课程成绩类和分项成绩类组成。
期末考试共分为选择题和编程题两种题型。立体图形问题和魔方问题考察了多态与继承的知识。display(RubikCube cube)方法是Main类中定义的静态方法,用于用户输出魔方的信息,体现了多态性。魔方排序题目中,RubikCube类要实现Comparable接口,体现了接口的知识。
设计与分析:
7-3 课程成绩统计程序-2 分数 60 作者 蔡轲 单位 南昌航空大学课程成绩统计程序-2在第一次的基础上增加了实验课,以下加粗字体显示为本次新增的内容。
某高校课程从性质上分为:必修课、选修课、实验课,从考核方式上分为:考试、考察、实验。
考试的总成绩由平时成绩、期末成绩分别乘以权重值得出,比如平时成绩权重0.3,期末成绩权重0.7,总成绩=平时成绩*0.3+期末成绩*0.7。
考察的总成绩直接等于期末成绩
实验的总成绩等于课程每次实验成绩的平均分
必修课的考核方式必须为考试,选修课可以选择考试、考察任一考核方式。实验课的成绩必须为实验。
1、输入:
包括课程、课程成绩两类信息。
课程信息包括:课程名称、课程性质、考核方式(可选,如果性质是必修课,考核方式可以没有)三个数据项。
课程信息格式:课程名称+英文空格+课程性质+英文空格+考核方式
课程性质输入项:必修、选修、实验
考核方式输入选项:考试、考察、实验
考试/考查课程成绩信息包括:学号、姓名、课程名称、平时成绩(可选)、期末成绩
考试/考查课程信息格式:学号+英文空格+姓名+英文空格+课程名称+英文空格+平时成绩+英文空格+期末成绩
实验课程成绩信息包括:学号、姓名、课程名称、实验次数、每次成绩
实验次数至少4次,不超过9次
实验课程信息格式:学号+英文空格+姓名+英文空格+课程名称+英文空格+实验次数+英文空格+第一次实验成绩+...+英文空格+最后一次实验成绩
以上信息的相关约束:
1)平时成绩和期末成绩的权重默认为0.3、0.7
2)成绩是整数,不包含小数部分,成绩的取值范围是【0,100】
3)学号由8位数字组成
4)姓名不超过10个字符
5)课程名称不超过10个字符
6)不特别输入班级信息,班级号是学号的前6位。
2、输出:
输出包含三个部分,包括学生所有课程总成绩的平均分、单门课程成绩平均分、单门课程总成绩平均分、班级所有课程总成绩平均分。
为避免误差,平均分的计算方法为累加所有符合条件的单个成绩,最后除以总数。
1)学生课程总成绩平均分按学号由低到高排序输出
格式:学号+英文空格+姓名+英文空格+总成绩平均分
如果某个学生没有任何成绩信息,输出:学号+英文空格+姓名+英文空格+"did not take any exams"
2)单门课程成绩平均分分为三个分值:平时成绩平均分(可选)、期末考试平均分、总成绩平均分,按课程名称的字符顺序输出
考试/考察课程成绩格式:课程名称+英文空格+平时成绩平均分+英文空格+期末考试平均分+英文空格+总成绩平均分
实验课成绩格式:课程名称+英文空格+总成绩平均分
如果某门课程没有任何成绩信息,输出:课程名称+英文空格+"has no grades yet"
3)班级所有课程总成绩平均分按班级由低到高排序输出
格式:班级号+英文空格+总成绩平均分
如果某个班级没有任何成绩信息,输出:班级名称+英文空格+ "has no grades yet"
异常情况:
1)如果解析某个成绩信息时,课程名称不在已输入的课程列表中,输出:学号+英文空格+姓名+英文空格+":"+课程名称+英文空格+"does not exist"
2)如果解析某个成绩信息时,输入的成绩数量和课程的考核方式不匹配,输出:学号+英文空格+姓名+英文空格+": access mode mismatch"
以上两种情况如果同时出现,按第一种情况输出结果。
3)如果解析某个课程信息时,输入的课程性质和课程的考核方式不匹配,输出:课程名称+" : course type & access mode mismatch"
4)格式错误以及其他信息异常如成绩超出范围等,均按格式错误处理,输出"wrong format"
5)若出现重复的课程/成绩信息,只保留第一个课程信息,忽略后面输入的。
信息约束:
1)成绩平均分只取整数部分,小数部分丢弃
参考类图(与第一次相同,其余内容自行补充):
输入样例1:
在这里给出一组输入。例如:
java 实验 实验
20201103 张三 java 4 70 80 90
end
输出样例1:
在这里给出相应的输出。例如:
20201103 张三 : access mode mismatch
20201103 张三 did not take any exams
java has no grades yet
202011 has no grades yet
输入样例2:
在这里给出一组输入。例如:
java 实验 实验
20201103 张三 java 3 70 80 90
end
输出样例2:
在这里给出相应的输出。例如:
wrong format
java has no grades yet
输入样例3:
在这里给出一组输入。例如:
java 必修 实验
20201103 张三 java 3 70 80 90 100
end
输出样例3:
在这里给出相应的输出。例如:
java : course type & access mode mismatch
wrong format
输入样例4:
在这里给出一组输入。例如:
java 必修 实验
20201103 张三 java 4 70 80 90 105
end
输出样例4:
在这里给出相应的输出。例如:
java : course type & access mode mismatch
wrong format
输入样例5:
在这里给出一组输入。例如:
java 选修 考察
C语言 选修 考察
java实验 实验 实验
编译原理 必修 考试
20201101 王五 C语言 76
20201216 李四 C语言 78
20201307 张少军 编译原理 82 84
20201103 张三 java实验 4 70 80 90 100
20201118 郑觉先 java 80
20201328 刘和宇 java 77
20201220 朱重九 java实验 4 60 60 80 80
20201132 王萍 C语言 40
20201302 李梦涵 C语言 68
20201325 崔瑾 编译原理 80 84
20201213 黄红 java 82
20201209 赵仙芝 java 76
end
输出样例5:
在这里给出相应的输出。例如:
20201101 王五 76
20201103 张三 85
20201118 郑觉先 80
20201132 王萍 40
20201209 赵仙芝 76
20201213 黄红 82
20201216 李四 78
20201220 朱重九 70
20201302 李梦涵 68
20201307 张少军 83
20201325 崔瑾 82
20201328 刘和宇 77
C语言 65 65
java 78 78
java实验 77
编译原理 81 84 82
202011 70
202012 76
202013 77
import java.text.Collator; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Scanner; public class Main { static boolean isNumber(String isNumber){ try{ int a=Integer.parseInt(isNumber); } catch (NumberFormatException e) { return false; } return true; } public static void main(String[] args) { Scanner input=new Scanner(System.in); String str; studentList students=new studentList(); InputMatching matching=new InputMatching(); chooseCourseList choose=new chooseCourseList(); Cls cls=new Cls(); courseList course=new courseList(); String str1,str2,str3; while(true){ str=input.nextLine(); if(isNumber(str.split(" ")[0]))break; if(str.equals("end"))break; if(InputMatching.matchingInput(str) != 1){ System.out.println("wrong format"); continue; } str1=str.split(" ")[0]; if(course.searchCourse(str1))continue; str2=str.split(" ")[1]; str3=str.split(" ")[2]; if((str2.equals("必修")&&str3.equals("考察"))||(str2.equals("实验")&&!str3.equals("实验")||(!str2.equals("实验")&&str3.equals("实验")))){ System.out.println(str.split(" ")[0]+" : course type & access mode mismatch"); continue; } if(course.searchCourse(str1))continue; course.courses.add(course.addCourse(str1,str2,str3)); } String number,name,subject; int UsualGrades,FinalGrades; boolean flag=false; while(!str.equals("end")){ if(flag)str=input.nextLine(); flag=true; if(str.equals("end"))break; String ssr=str.split(" ")[0]+" "+str.split(" ")[1]+" "+str.split(" ")[2]+" "+str.split(" ")[3]; if (InputMatching.matchingInput(ssr) != 2&&InputMatching.matchingInput(ssr) != 3&&course.searchQuality(str.split(" ")[2])!=2) { System.out.println("wrong format");// 字符串符合成绩信息模式 continue; } if(((Integer.parseInt(str.split(" ")[3]))<4||(Integer.parseInt(str.split(" ")[3]))>9)&&str.split(" ").length>5){ System.out.println("wrong format"); continue; } number=str.split(" ")[0]; String Class = number.substring(0, 6); if (!cls.searchCls(Class)) cls.cls.add(cls.addCls(Class)); name=str.split(" ")[1]; students.stu.add(students.addStudent(number,name)); subject=str.split(" ")[2]; try{ if (course.searchQuality(subject) == 1) { UsualGrades = Integer.parseInt(str.split(" ")[3]); if(choose.searchCourse(subject)&&choose.searchId(number))continue; FinalGrades = Integer.parseInt(str.split(" ")[4]); students.students.add(students.addStudentCompulsory(number, name, subject, UsualGrades, FinalGrades)); } else if (course.searchQuality(subject) == 0) { UsualGrades = Integer.parseInt(str.split(" ")[3]); if(choose.searchCourse(subject)&&choose.searchId(number))continue; if(str.split(" ").length>4){System.out.println(number+" "+name+" : access mode mismatch");continue;} students.students.add(students.addStudentTake(number, name, subject, UsualGrades)); } else if (course.searchQuality(subject) == -1) { System.out.println(subject + " does not exist"); } else if(course.searchQuality(subject) == 2){ int testNumber=Integer.parseInt(str.split(" ")[3]); if(str.split(" ").length-4!=testNumber) { System.out.println(number+" "+name+" : access mode mismatch"); continue; } int sum=0; for(int i=0;i<testNumber;i++){ sum+=Integer.parseInt(str.split(" ")[4+i]); } sum/=testNumber; students.students.add(students.addExperimentalGrades(number, name, subject, sum)); } } catch (ArrayIndexOutOfBoundsException e) { System.out.println(number+" "+name+" : access mode mismatch"); } } chooseCourseList chooses=new chooseCourseList(); chooses.getAverageGrade(students,course,cls); } } class student{ int experimentalGrades; String number; String name; String course; int UsualGrades=0; int FinalGrades=0; String Class; int grade=0; public static Comparator<student> getNumberComparator() { return Comparator.comparing(s -> s.number); } } class course{ String name; String quality; String manner; public static Comparator<course> getChineseNameComparator() { final Collator collator = Collator.getInstance(java.util.Locale.CHINA); // 获取中文排序规则 return (c1, c2) -> collator.compare(c1.name, c2.name); } } class courseList{ ArrayList<course>courses=new ArrayList<>(); boolean searchCourse(String CourseName){ for (course cours : courses) if (cours.name.equals(CourseName)) return true; return false; } course addCourse( String name,String quality,String manner){ course newCourse=new course(); newCourse.name=name; newCourse.quality=quality; newCourse.manner=manner; return newCourse; } int searchQuality(String subject){ for (course cours : courses) { if (cours.name.equals(subject) && cours.quality.equals("必修")) return 1; else if (cours.name.equals(subject) && cours.manner.equals("考试")) return 1; else if (cours.name.equals(subject)&&cours.quality.equals("实验"))return 2; else if (cours.name.equals(subject)&&cours.manner.equals("实验"))return 2; else if (cours.name.equals(subject)) return 0; } return -1; } } class studentList { ArrayList<student> students = new ArrayList<>(); ArrayList<student> stu = new ArrayList<>(); student addStudentCompulsory(String number, String name, String course, int UsualGrades, int FinalGrades) { student newStudent = new student(); chooseCourseList newChoose = new chooseCourseList(); newStudent.name = name; if(chooseCourseList.searchCourse(course)&& chooseCourseList.chooseCourse.get(chooseCourseList.searchCourseInt(course)).name.equals(name)&& chooseCourseList.chooseCourse.get(chooseCourseList.searchCourseInt(course)).number.equals(number)) return null; Cls newCls = new Cls(); newStudent.number = number; newStudent.course = course; newStudent.grade = (int) (FinalGrades * 0.7 + UsualGrades * 0.3); String Class = number.substring(0, 6); if (!newCls.searchCls(Class)) newCls.cls.add(newCls.addCls(Class)); chooseCourseList.chooseCourse.add(newChoose.addChoose(number, name, course, Class, UsualGrades, FinalGrades, newStudent.grade)); return newStudent; } student addStudentTake(String number, String name, String course, int UsualGrades) { student newStudent = new student(); newStudent.name = name; newStudent.number = number; newStudent.course = course; newStudent.grade = UsualGrades; String Class=number.substring(0,6); chooseCourseList newChoose = new chooseCourseList(); if(chooseCourseList.searchCourse(course)&& chooseCourseList.chooseCourse.get(chooseCourseList.searchCourseInt(course)).name.equals(name)&& chooseCourseList.chooseCourse.get(chooseCourseList.searchCourseInt(course)).number.equals(number)) return null; chooseCourseList.chooseCourse.add(newChoose.addChooseTake(number, name, course, Class, UsualGrades, newStudent.grade)); return newStudent; } student addExperimentalGrades(String number, String name, String course, int experimentalGrades) { student newStudent = new student(); newStudent.name = name; newStudent.number = number; newStudent.course = course; newStudent.experimentalGrades = experimentalGrades; newStudent.grade = experimentalGrades; String Class=number.substring(0,6); chooseCourseList newChoose = new chooseCourseList(); if(chooseCourseList.searchCourse(course)&& chooseCourseList.chooseCourse.get(chooseCourseList.searchCourseInt(course)).name.equals(name)&& chooseCourseList.chooseCourse.get(chooseCourseList.searchCourseInt(course)).number.equals(number)) return null; chooseCourseList.chooseCourse.add(newChoose.addChooseExperimental(number, name, course, Class, experimentalGrades)); return newStudent; } student addStudent(String id, String name) { student newStudent = new student(); newStudent.number = id; newStudent.name = name; return newStudent; } boolean searchStudent(String name) { for (student student : students) { if (student.name.equals(name)) return true; } return false; } } class Cls { private static int nextIndex = 0; String id; private int index; ArrayList<Cls> cls = new ArrayList<>(); public Cls addCls(String cl) { Cls newCls = new Cls(); newCls.id = cl; // 新增元素的 index 应该为当前列表长度 newCls.index = nextIndex++; cls.add(newCls); return newCls; } public boolean searchCls(String id) { for (Cls cl : cls) { if (cl.id.equals(id)) { return true; } } return false; } public static Comparator<Cls> getIndexComparator() { return Comparator.comparing(c -> c.id); } } class InputMatching { static String stuNumMatching = "[0-9]{8}";//8个0-9的数字 static String stuNameMatching = "\\S{1,10}";//1到10个非空格(TAB)字符 static String scoreMatching = "([1-9]?[0-9]|100)"; static String courseNameMatching = "\\S{1,10}";//1到10个非空格(TAB)字符 static String courseTypeMatching = "(选修|必修|实验)"; static String checkcourseTypeMatching = "(考试|考察|实验)"; //cousrInput用于定义课程信息模式(正则表达式) static String courseInput = courseNameMatching + " " + courseTypeMatching + " " + checkcourseTypeMatching; //scoreInput用于定义成绩信息模式(正则表达式) static String scoreInput1 = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + scoreMatching + "(scoreMatching)?"; static String scoreInput2 = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + scoreMatching + "(scoreMatching)?"+" "+scoreMatching + "(scoreMatching)?"; public static int matchingInput(String s) { if (matchingCourse(s)) { return 1; } if (matchingScore1(s)) { return 2; } if (matchingScore2(s)) { return 3; } return 0; } static boolean matchingCourse(String s) { return s.matches(courseInput); } static boolean matchingScore1(String s) { return s.matches(scoreInput1); } static boolean matchingScore2(String s) { return s.matches(scoreInput2); } } class chooseCourseList{ static ArrayList<student> chooseCourse=new ArrayList<>(); static boolean searchId(String id){ for (student student : chooseCourse) if (student.number.equals(id)) return true; return false; } static boolean searchCourse(String course){ for (student student : chooseCourse) if (student.course.equals(course)) return true; return false; } static int searchCourseInt(String course){ for(int i=0;i<chooseCourse.size();i++) if(chooseCourse.get(i).course.equals(course))return i; return -1; } static boolean searchClass(String Class){ for (student student : chooseCourse) if (student.Class.equals(Class)) return true; return false; } student addChoose(String id,String name,String course,String Class,int UsualGrades,int FinalGrades,int grade ) { student newStudent=new student(); newStudent.Class=Class; newStudent.number=id; newStudent.name=name; newStudent.course=course; newStudent.UsualGrades=UsualGrades; newStudent.FinalGrades=FinalGrades; newStudent.grade=grade; return newStudent; } student addChooseTake(String id,String name,String course,String Class,int UsualGrades,int grade ) { student newStudent=new student(); newStudent.Class=Class; newStudent.number=id; newStudent.name=name; newStudent.course=course; newStudent.UsualGrades=UsualGrades; newStudent.grade=grade; return newStudent; } student addChooseExperimental(String id,String name,String course,String Class,int experimental ) { student newStudent=new student(); newStudent.Class=Class; newStudent.number=id; newStudent.name=name; newStudent.course=course; newStudent.experimentalGrades=experimental; newStudent.grade=experimental; return newStudent; } public int getAverageGrades(String id){ int sum=0,cnt=0; for (student student : chooseCourse) { if (student.number.equals(id)) { sum += student.grade; cnt++; } } return sum / cnt; } public int getAverageCourseUsualGrades(String course){ int sum=0,cnt=0; for (student student : chooseCourse) { if (student.course.equals(course)) { sum += student.UsualGrades; cnt++; } } return sum / cnt; } public int getAverageCourseFinalGrades(String course){ int sum=0,cnt=0; for (student student : chooseCourse) { if (student.course.equals(course)) { sum += student.FinalGrades; cnt++; } } return sum / cnt; } public int getAverageCourseGrades(String course){ int sum=0,cnt=0; for (student student : chooseCourse) { if (student.course.equals(course)) { sum += student.grade; cnt++; } } return sum / cnt; } public int getAverageExperimentalGrades(String course){ int sum=0,cnt=0; for (student student : chooseCourse) { if (student.course.equals(course)) { sum += student.experimentalGrades; cnt++; } } return sum / cnt; } public int getClassAverageGrades(String Class){ int sum=0,cnt=0; for (student student : chooseCourse) { if (student.Class.equals(Class)) { sum += student.grade; cnt++; } } return sum / cnt; } public void getAverageGrade(studentList students,courseList courses,Cls cls){ students.stu.sort(student.getNumberComparator()); cls.cls.sort(Cls.getIndexComparator()); courses.courses.sort(course.getChineseNameComparator()); for(int i=0;i<students.stu.size();i++){ int flag=0; for(int j=0;j<i;j++){ if(students.stu.get(j).number.equals(students.stu.get(i).number)){flag=1;break;} } if(flag==1)continue; if(searchId(students.stu.get(i).number)){ System.out.println(students.stu.get(i).number+" "+students.stu.get(i).name+" "+getAverageGrades(students.stu.get(i).number)); } else{ System.out.println(students.stu.get(i).number+" "+students.stu.get(i).name+" did not take any exams"); } } for(int i=0;i<courses.courses.size();i++){ if(searchCourse(courses.courses.get(i).name)){ if(courses.courses.get(i).manner.equals("考试")){ System.out.println(courses.courses.get(i).name+" "+getAverageCourseUsualGrades(courses.courses.get(i).name) +" "+getAverageCourseFinalGrades(courses.courses.get(i).name)+" "+getAverageCourseGrades(courses.courses.get(i).name)); } else if(courses.courses.get(i).manner.equals("考察"))System.out.println(courses.courses.get(i).name+" "+getAverageCourseUsualGrades(courses.courses.get(i).name) +" "+getAverageCourseGrades(courses.courses.get(i).name)); else System.out.println(courses.courses.get(i).name+" "+getAverageExperimentalGrades(courses.courses.get(i).name)); } else{ System.out.println(courses.courses.get(i).name+" has no grades yet"); } } for(int i=0;i<cls.cls.size();i++){ int flag=0; for(int j=0;j<i;j++){ if(cls.cls.get(j).equals(cls.cls.get(i))){flag=1;break;} } if(flag==1)continue; if(searchClass(cls.cls.get(i).id)){ System.out.println(cls.cls.get(i).id+" "+getClassAverageGrades(cls.cls.get(i).id)); } else{ System.out.println(cls.cls.get(i).id+" has no grades yet"); } } } }
这段代码是一个Java程序,主要包括了学生、课程、选课列表等相关类的定义,并且包含了一些输入匹配和成绩统计的功能。
在程序中,有如下几个类:
-
Main
类:包含了程序的入口和主要逻辑。在main
方法中,通过输入流读取用户输入,然后根据输入执行相应的操作,包括录入课程信息和学生成绩信息,最后调用chooseCourseList
类的方法进行成绩统计。 -
student
类:表示学生的实体类,包括学号、姓名、课程、平时成绩、期末成绩等属性。 -
course
类:表示课程的实体类,包括课程名称、质量(必修、选修)和方式(考试、考察、实验)等属性。 -
courseList
类:课程列表类,包含了课程的集合,以及对课程的一些操作,比如搜索课程、添加课程等。 -
studentList
类:学生列表类,包含了学生的集合,以及对学生的一些操作,比如添加学生、搜索学生等。 -
Cls
类:班级类,表示班级实体,包含了班级ID等属性。 -
InputMatching
类:输入匹配类,用于匹配输入的格式是否符合要求。 -
chooseCourseList
类:选课列表类,包含了选课列表的集合,以及对选课列表的一些操作,比如搜索学生、搜索课程、计算平均成绩等。
总的来说,这段代码实现了一个简单的学生成绩管理系统,通过输入学生的成绩和课程信息,最后可以统计学生的平均成绩、课程的平均成绩以及班级的平均成绩等信息。
7-3 魔方排序问题 分数 20 作者 段喜龙 单位 南昌航空大学在魔方问题的基础上,重构类设计,实现列表内魔方的排序功能(按照魔方的体积进行排序)。
提示:题目中RubikCube类要实现Comparable接口。
其中,Main类源码如下(可直接拷贝使用):
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
String color;
int layer;
double side;
RubikCube cube;
ArrayList<RubikCube> list = new ArrayList<>();
int choice = input.nextInt();
while(choice != 0) {
switch(choice) {
case 1://SquareCube
color = input.next();
layer = input.nextInt();
side = input.nextDouble();
cube = new SquareCube(color, layer,new Cube(side));
list.add(cube);
break;
case 2://RegularPyramidCube
color = input.next();
layer = input.nextInt();
side = input.nextDouble();
cube = new RegularPyramidCube(color, layer,new RegularPyramid(side));
list.add(cube);
break;
}
choice = input.nextInt();
}
list.sort(Comparator.naturalOrder());//正向排序
for(int i = 0; i < list.size(); i++) {
System.out.print(list.get(i).getColor() + " " +
String.format("%.2f", list.get(i).getArea()) + " " +
String.format("%.2f", list.get(i).getVolume()) );
System.out.println("");
}
}
}
输入格式:
输入魔方类型(1:正方体魔方;2:正三棱锥魔方;0:结束输入)
魔方颜色、魔方阶数、魔方单元正方体、正三棱锥边长
..循环..
输出格式:
按魔方体积升序输出列表中各魔方的信息(实型数均保留两位小数),输出样式参见输出样例。
输入样例:
在这里给出一组输入。例如:
1 blue 3 4.5
2 red 4 2.1
1 yellow 5 2.3
2 black 4 9.42
1 white 4 5.4423
0
输出样例:
在这里给出相应的输出。例如:
red 122.21 69.85
yellow 793.50 1520.88
blue 1093.50 2460.38
black 2459.14 6304.73
white 2843.39 10316.38
import java.util.ArrayList; import java.util.Comparator; import java.util.Scanner; abstract class GeometricShape { public abstract double getSurfaceArea(); public abstract double getVolume(); } class Cube extends GeometricShape { private double side; public Cube(double side) { this.side = side; } public double getSurfaceArea() { return 6 * side * side; } public double getVolume() { return side * side * side; } } class RegularPyramid extends GeometricShape { private double side; private double height; public RegularPyramid(double side) { this.side = side; this.height = side * Math.sqrt(2.0 / 3.0); } public double getSurfaceArea() { double s=Math.sqrt(3)*side*side; return s; } public double getVolume() { double v=Math.sqrt(2)/12*side*side*side; return v; } } class RubikCube implements Comparable<RubikCube> { private String color; private int layer; private GeometricShape shape; public RubikCube(String color, int layer, GeometricShape shape) { this.color = color; this.layer = layer; this.shape = shape; } public String getColor() { return color; } public double getArea() { return shape.getSurfaceArea() * layer * layer; } public double getVolume() { return shape.getVolume() * layer * layer * layer; } public int compareTo(RubikCube other) { if (this.getVolume() < other.getVolume()) { return -1; } else if (this.getVolume() > other.getVolume()) { return 1; } return 0; } } class SquareCube extends RubikCube { public SquareCube(String color, int layer, Cube cube) { super(color, layer, cube); } } class RegularPyramidCube extends RubikCube { public RegularPyramidCube(String color, int layer, RegularPyramid pyramid) { super(color, layer, pyramid); } } public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); String color; int layer; double side; RubikCube cube; ArrayList<RubikCube> list = new ArrayList<>(); int choice = input.nextInt(); while (choice != 0) { switch (choice) { case 1://SquareCube color = input.next(); layer = input.nextInt(); side = input.nextDouble(); cube = new SquareCube(color, layer,new Cube(side)); list.add(cube); break; case 2://RegularPyramidCube color = input.next(); layer = input.nextInt(); side = input.nextDouble(); cube = new RegularPyramidCube(color, layer,new RegularPyramid(side)); list.add(cube); break; } choice = input.nextInt(); } list.sort(Comparator.naturalOrder());//正向排序 for (int i = 0; i < list.size(); i++) { System.out.print(list.get(i).getColor() + " " + String.format("%.2f", list.get(i).getArea()) + " " + String.format("%.2f", list.get(i).getVolume())); System.out.println(""); } } }
这段代码是一个简单的立方体(Cube)和正四面体(RegularPyramid)的计算程序。其中,GeometricShape 是一个抽象类,Cube 和 RegularPyramid 是它的两个子类,分别表示立方体和正四面体。RubikCube 是一个实现了 Comparable 接口的类,表示魔方。SquareCube 和 RegularPyramidCube 是 RubikCube 的两个子类。
在 Main 类的 main 方法中,通过用户输入选择魔方类型(1 表示立方体,2 表示正四面体)。然后,根据用户输入的颜色、层数和边长创建相应类型的魔方对象,并将其加入到 list 列表中。最后,对 list 列表进行排序(按照魔方的体积从小到大),并输出每个魔方的颜色、表面积和体积。
这段代码的逻辑结构比较清晰,类之间的关系也比较明确。抽象类 GeometricShape 定义了计算表面积和体积的抽象方法,子类 Cube 和 RegularPyramid 分别实现了这两个方法。RubikCube 类实现了 Comparable 接口,用于比较魔方的体积大小。SquareCube 和 RegularPyramidCube 类分别是 RubikCube 的子类,表示魔方的两种具体形状。
代码中使用了 ArrayList 来存储创建的魔方对象,并使用 sort 方法对列表进行排序。输出时使用了 String.format 方法来格式化输出浮点数。
7-5 jmu-Java-03面向对象基础-05-覆盖 分数 5 作者 郑如滨 单位 集美大学Java每个对象都继承自Object,都有equals、toString等方法。
现在需要定义PersonOverride
类并覆盖其toString
与equals
方法。
1. 新建PersonOverride类
a. 属性:String name
、int age
、boolean gender
,所有的变量必须为私有(private)。
b. 有参构造方法,参数为name, age, gender
c. 无参构造方法,使用this(name, age,gender)
调用有参构造方法。参数值分别为"default",1,true
d.toString()
方法返回格式为:name-age-gender
e. equals
方法需比较name、age、gender,这三者内容都相同,才返回true
.
2. main方法
2.1 输入n1,使用无参构造方法创建n1个对象,放入数组persons1。
2.2 输入n2,然后指定name age gender
。每创建一个对象都使用equals方法比较该对象是否已经在数组中存在,如果不存在,才将该对象放入数组persons2。
2.3 输出persons1数组中的所有对象
2.4 输出persons2数组中的所有对象
2.5 输出persons2中实际包含的对象的数量
2.5 使用System.out.println(Arrays.toString(PersonOverride.class.getConstructors()));
输出PersonOverride的所有构造方法。
提示:使用ArrayList
代替数组大幅复简化代码,请尝试重构你的代码。
输入样例:
1
3
zhang 10 true
zhang 10 true
zhang 10 false
输出样例:
default-1-true
zhang-10-true
zhang-10-false
2
[public PersonOverride(), public PersonOverride(java.lang.String,int,boolean)]
import java.util.ArrayList; import java.util.HashSet; import java.util.Scanner; import java.util.Set; class PersonOverride { private String name; private int age; private boolean gender; public PersonOverride(String name, int age, boolean gender) { this.name = name; this.age = age; this.gender = gender; } public PersonOverride() { this("default", 1, true); } public String toString() { return name + "-" + age + "-" + gender; } public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null || getClass() != obj.getClass()) { return false; } PersonOverride person = (PersonOverride) obj; return age == person.age && gender == person.gender && name.equals(person.name); } public int hashCode() { return name.hashCode() + age + (gender ? 1 : 0); } } public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int n1 = scanner.nextInt(); ArrayList<PersonOverride> persons1 = new ArrayList<>(); for (int i = 0; i < n1; i++) { persons1.add(new PersonOverride()); } int n2 = scanner.nextInt(); ArrayList<PersonOverride> persons2 = new ArrayList<>(); Set<String> personSet = new HashSet<>(); // 使用Set来去重 for (int i = 0; i < n2; i++) { String name = scanner.next(); int age = scanner.nextInt(); boolean gender = scanner.nextBoolean(); String personString = name + "-" + age + "-" + gender; if (!personSet.contains(personString)) { persons2.add(new PersonOverride(name, age, gender)); personSet.add(personString); } } // 输出persons1数组中的所有对象 for (PersonOverride person : persons1) { System.out.println(person); } // 输出persons2数组中的所有对象 for (PersonOverride person : persons2) { System.out.println(person); } // 输出persons2中实际包含的对象的数量 System.out.println(personSet.size()); // 输出PersonOverride的所有构造方法,按照参数数量从少到多排序 java.lang.reflect.Constructor<?>[] constructors = PersonOverride.class.getDeclaredConstructors(); java.util.Arrays.sort(constructors, (a, b) -> Integer.compare(a.getParameterCount(), b.getParameterCount())); System.out.println(java.util.Arrays.toString(constructors)); } }
这段代码是一个简单的示例,涉及到类的重写(override)、集合类的使用以及反射。
首先,定义了一个 PersonOverride
类,该类包含了姓名(name)、年龄(age)和性别(gender)三个属性。类中定义了构造方法、toString
方法、equals
方法和 hashCode
方法。toString
方法用于将对象的属性以字符串形式输出,equals
方法用于判断两个对象是否相等,hashCode
方法用于生成对象的哈希码。
在 Main
类的 main
方法中,首先通过 Scanner
对象获取用户输入的整数 n1
和 n2
,分别表示要创建的 persons1
和 persons2
的对象数量。
接下来,使用循环创建 persons1
列表,并添加 PersonOverride
对象。persons1
列表中的对象都是使用默认构造方法创建的。
然后,使用循环创建 persons2
列表,并添加 PersonOverride
对象。在创建对象之前,首先根据用户输入的姓名(name)、年龄(age)和性别(gender)拼接成一个字符串 personString
。然后,通过判断 personSet
集合中是否已经包含该字符串来去重,如果不包含,则创建 PersonOverride
对象并添加到 persons2
列表和 personSet
集合中。
接下来,分别遍历输出 persons1
和 persons2
列表中的对象,使用 System.out.println
方法输出对象的字符串表示。
然后,输出 personSet
集合的大小,即 persons2
中实际包含的对象的数量。
最后,通过反射获取 PersonOverride
类的所有构造方法,并按照参数数量从少到多排序。使用 java.util.Arrays.sort
方法和 lambda 表达式实现排序,并用 System.out.println
方法输出排序后的构造方法数组。
(3)踩坑心得:
7-2:
这段代码中的一些缺陷包括:
-
命名不够规范:在代码中出现了一些命名不够规范的情况,比如
Cls
类名应该改为Class
或者Clazz
更为合适;InputMatching
类名应该改为InputMatcher
更为符合 Java 命名规范。 -
某些部分的逻辑复杂度过高:在代码中,有一些方法的逻辑复杂度过高,比如
chooseCourseList
类中的calculateAvgScore
方法;此外,还有一些方法命名过长,比如studentList
类中的searchStudentByCourseNameAndScore
方法。 -
缺乏异常处理和边界检查:在代码中,缺乏对输入的异常处理和边界检查。比如,程序没有检查输入的成绩是否合法,以及学生、课程、选课列表等对象是否存在,这会导致程序崩溃或者产生错误的计算结果。
-
代码可读性较差:在代码中,函数、类的命名不够清晰易懂,缺少注释,导致代码的可读性较差,难以理解代码的意图和实现逻辑。
下面给出一些具体的例子:
- 在
Main
类中,输入格式不符合要求时,程序会抛出NumberFormatException
异常,但是没有对其进行处理,导致程序崩溃。
case 3:
System.out.println("请输入学生学号、课程编号、平时成绩和期末成绩,以空格分隔:");
String inputScore = scanner.nextLine();
String[] scoreArr = inputScore.split(" ");
Student student = studentList.searchStudentByNum(scoreArr[0]);
Course course = courseList.searchCourseByCode(scoreArr[1]);
int dailyScore = Integer.parseInt(scoreArr[2]); // 可能抛出 NumberFormatException 异常
int finalScore = Integer.parseInt(scoreArr[3]); // 可能抛出 NumberFormatException 异常
if (student != null && course != null) {
student.setScore(course, dailyScore, finalScore);
System.out.println("成绩录入成功!");
} else {
System.out.println("无法找到该学生或课程!");
}
break;
- 在
courseList
类中,搜索课程的方法命名过长,可读性较差,建议改为searchCourse
更为简洁易懂。
public Course searchCourseByCode(String code) {
for (Course course : courses) {
if (course.getCode().equals(code)) {
return course;
}
}
return null;
}
- 在
chooseCourseList
类中,计算平均成绩的方法逻辑较为复杂,可以进行重构优化,使代码更加清晰易懂。
public double calculateAvgScore(List<Student> studentList) {
int sum = 0;
int count = 0;
for (Student student : studentList) {
if (student.getScore(course) > 0) {
sum += student.getScore(course);
count++;
}
}
if (count == 0) {
return 0;
}
return sum / (double)count;
}
期末考试 7-3
代码中没有处理用户输入的异常情况,比如输入非法字符或负数。在实际应用中,可能需要添加相应的异常处理机制来保证程序的健壮性。另外,代码中的变量命名和注释也可以进一步改进以提高代码的可读性。
另外:
输入样例:
在这里给出一组输入。例如:
1 blue 3 4.5
2 red 4 2.1
1 yellow 5 2.3
2 black 4 9.42
1 white 4 5.4423
0
输出样例:
在这里给出相应的输出。例如:
red 122.21 69.85 yellow 793.50 1520.88 blue 1093.50 2460.38 black 2459.14 6304.73 white 2843.39 10316.38在运行测试用例时,对于
yellow 793.50 1520.88输出结果是
yellow 793.50 1520.87 可能是因为在计算体积的类中return返回的数值类型是double✖int导致的数据偏差,因此需要进行修改
7-5 jmu-Java-03面向对象基础-05-覆盖
在这段代码中,存在以下潜在问题:
-
对用户输入没有进行验证:例如,当用户输入的年龄为负数或者字符串时,程序可能会出现异常。
-
在
PersonOverride
类中,equals
方法和hashCode
方法只考虑了姓名、年龄和性别属性是否相等,没有考虑其他属性。这种实现方式可能会导致两个对象在其他属性不相等的情况下被认为是相等的,从而影响程序的正确性。
针对这些问题,我们可以做出如下修改:
-
对用户输入进行验证:在获取用户输入之前,可以使用
Scanner
类提供的hasNextInt()
和nextLine()
等方法对用户输入进行验证,以确保用户输入的是合法的整数、布尔值或字符串等数据类型。 -
修改
equals
和hashCode
方法的实现:在比较两个对象是否相等时,应该考虑所有属性是否相等,而不仅仅是姓名、年龄和性别属性。修改equals
方法和hashCode
方法的实现如下:
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
PersonOverride person = (PersonOverride) obj;
return age == person.age && gender == person.gender && Objects.equals(name, person.name);
}
public int hashCode() {
return Objects.hash(name, age, gender);
}
其中,Objects.equals()
方法用于比较两个字符串是否相等,Objects.hash()
方法用于生成对象的哈希码。
(5)实验总结
在本次实验中,我们学习了如何在Java中进行对象比较和生成哈希码。通过实现 equals
方法和 hashCode
方法,可以确保对象在集合中的正确性和一致性。
在实验过程中,我们遇到了一些潜在问题,并进行了相应的修改。首先,我们对用户的输入进行了验证,确保输入的数据类型是合法的。其次,我们修改了 equals
和 hashCode
方法的实现,考虑了所有属性是否相等,以避免出现错误的对象比较结果。
通过这次实验,我学到了以下几点:
-
在Java中,对象比较可以通过重写
equals
方法来实现。在重写equals
方法时,需要考虑对象的所有属性是否相等,而不仅仅是部分属性。 -
为了确保对象在集合中的正确性,还需要重写
hashCode
方法。在重写hashCode
方法时,应该根据对象的所有属性来生成哈希码,以保证相等的对象具有相等的哈希码。 -
对用户输入进行验证是一种良好的编程习惯,可以避免程序因为非法输入而出现异常或错误结果。
-
在实际应用中,可以使用集合类(如
ArrayList
、HashSet
)来存储和操作对象,从而简化代码的编写和处理。 - 抽象类作为一种特殊类型的类,只能被继承而不能被实例化,可以提高代码的复用性和可维护性;多态是面向对象编程的一种核心概念,让代码更加灵活和简洁,提高了程序的可扩展性和可重用性
总的来说,本次实验加深了我对Java对象比较和哈希码的理解,也让我更加熟悉了如何编写符合规范的代码。这些知识和技巧在实际的软件开发中都非常重要,能够帮助我们编写出更健壮、高效和可维护的程序。
标签:return,String,int,equals,BLOG,course,name From: https://www.cnblogs.com/3290604331a/p/17891010.html