在Java编程领域中,掌握如何读取和处理用户输入数据是非常基础和重要的一步。我们需要从用户那里获取输入数据,并根据输入数据进行相应的操作或计算。在这篇博客中,我们将会探讨如何在Java程序中读取和处理用户输入数据,以及如何利用这些数据来完成一些常见的任务,比如计算平均分和总成绩平均分。
7-1 课程成绩统计程序-1
1 class Course { 2 5 String name; // 课程名称 3 6 String type; // 课程性质(必修/选修) 4 7 String access; // 考核方式(考试/考察) 5 8 List<Integer> scores = new ArrayList<>(); // 成绩列表 6 9 7 10 // 构造函数,用于初始化课程对象 8 11 public Course(String name, String type, String access) { 9 12 this.name = name; 10 13 this.type = type; 11 14 this.access = access; 12 15 } 13 16 14 17 // 添加成绩,返回添加是否成功 15 18 public boolean addScore(int score) { // 成绩 16 19 if (scores.size() == 0) { // 如果没有添加过成绩 17 20 scores.add(score); 18 21 return true; 19 22 } else if (access.equals("考试") && scores.size() == 2) { // 如果是考试课程,并且已经添加过平时成绩和期末成绩 20 23 return false; // 返回添加失败 21 24 } else if (access.equals("考察") && scores.size() == 1) { // 如果是考察课程,并且已经添加过期末成绩 22 25 return false; // 返回添加失败 23 26 } else { 24 27 scores.add(score); 25 28 return true; 26 29 } 27 30 } 28 31 29 32 // 计算平均分,只取整数部分 30 33 public int averageScore() { 31 34 int total = 0; 32 35 for (int score : scores) { 33 36 total += score; 34 37 } 35 38 return total / scores.size(); 36 39 } 37 40 38 41 // 判断两个课程是否相同,根据课程名称判断 39 42 public boolean equals(Course other) { 40 43 return this.name.equals(other.name); 41 44 } 42 45 } 43 46
这个类是一个课程类,里面包含了课程名称、课程性质、考核方式和成绩列表等信息。下面对这个类进行详细分析:
1. 属性:
- name:课程名称,类型为String。
- type:课程性质,类型为String。
- access:考核方式,类型为String。
- scores:成绩列表,类型为List<Integer>。
2. 构造函数:
- Course(String name, String type, String access):初始化课程对象,需要传入课程名称、课程性质和考核方式。
3. 方法:
- addScore(int score):添加成绩,并返回添加是否成功。如果是考试课程,并且已经添加过平时成绩和期末成绩,或者是考察课程,并且已经添加过期末成绩,则添加失败,返回false;否则,添加成功,返回true。
- averageScore():计算平均分,只取整数部分。遍历成绩列表,将成绩相加,然后除以成绩列表的长度,最后返回结果。
- equals(Course other):判断两个课程是否相同,根据课程名称判断。如果两个课程的名称相同,则返回true;否则,返回false。
在这个课程类中,我们使用了List和ArrayList等Java集合框架中的功能,来存储和操作成绩列表。这样的设计可以使代码更加简洁、易读和易维护。此外,我们还考虑了不同类型的课程所需要的不同操作,比如考试课程需要添加平时成绩和期末成绩,而考察课程只需要添加期末成绩。这样的设计可以使代码更加具有通用性和可扩展性。
1 class Student { 2 49 String id; // 学号 3 50 String name; // 姓名 4 51 List<Course> courses = new ArrayList<>(); // 选修的课程列表 5 52 6 53 // 构造函数,用于初始化学生对象 7 54 public Student(String id, String name) { 8 55 this.id = id; 9 56 this.name = name; 10 57 } 11 58 12 59 // 添加选修课程 13 60 public void addCourse(Course course) { 14 61 courses.add(course); 15 62 } 16 63 17 64 // 根据课程名称查找选修的课程,如果找不到返回 null 18 65 public Course findCourse(String name) { 19 66 for (Course course : courses) { 20 67 if (course.name.equals(name)) { 21 68 return course; 22 69 } 23 70 } 24 71 return null; 25 72 } 26 73 27 74 // 计算课程总成绩平均分(只包括已经添加完整成绩信息的课程) 28 75 public int averageTotalScore() { 29 76 int total = 0; 30 77 int count = 0; 31 78 for (Course course : courses) { 32 79 if (course.scores.size() == 2 || course.scores.size() == 1 && course.access.equals("考察")) { // 如果成绩信息完整 33 80 total += course.averageScore(); 34 81 count++; 35 82 } 36 83 } 37 84 if (count == 0) { 38 85 return -1; // 表示没有符合条件的课程,用于特殊输出 39 86 } 40 87 return total / count; 41 88 } 42 89 }
这个类是一个学生类,里面包含了学生的学号、姓名和选修的课程列表等信息。下面对这个类进行详细分析:
1. 属性:
- id:学号,类型为String。
- name:姓名,类型为String。
- courses:选修的课程列表,类型为List<Course>。
2. 构造函数:
- Student(String id, String name):初始化学生对象,需要传入学号和姓名。
3. 方法:
- addCourse(Course course):添加选修课程。将课程对象加入到选修的课程列表中。
- findCourse(String name):根据课程名称查找选修的课程,如果找到则返回该课程对象;否则返回null。
- averageTotalScore():计算课程总成绩平均分(只包括已经添加完整成绩信息的课程)。遍历选修的课程列表,对于每个课程,如果其成绩信息完整,则计算该课程的平均分并将其加入总成绩中,同时计数器加1。最后,如果计数器为0,则表示没有符合条件的课程,返回-1;否则,计算总成绩平均分并返回结果。
在这个学生类中,我们使用了List和ArrayList等Java集合框架中的功能,来存储和操作选修的课程列表。这样的设计可以使代码更加简洁、易读和易维护。此外,我们还考虑了只计算已经添加完整成绩信息的课程的总成绩平均分,这样的设计可以使计算结果更加准确和有意义。另外,我们还在计算总成绩平均分时,加入了特殊输出的处理,以方便后续的输出操作。
1 91 public class Main { 2 92 public static void main(String[] args) { 3 93 Scanner scanner = new Scanner(System.in); 4 94 5 95 Map<String, Course> courseMap = new HashMap<>(); // 保存所有课程信息 6 96 Map<String, Student> studentMap = new TreeMap<>(); // 保存所有学生信息(按学号排序) 7 97 8 98 while (scanner.hasNextLine()) { // 循环读入所有输入信息 9 99 try { 10 100 String[] parts = scanner.nextLine().split(" "); 11 101 if (parts.length != 3 && parts.length != 5) { // 如果输入不符合格式要求 12 102 System.out.println("wrong format"); 13 103 continue; 14 104 } 15 105 if (parts.length == 3) { // 如果输入为课程信息 16 106 String name = parts[0]; 17 107 String type = parts[1]; 18 108 String access = parts[2]; 19 109 if (type.equals("必修") && access.equals("")) { // 如果是必修课程,但没有指定考核方式 20 110 System.out.println(name + " : access mode missing"); 21 111 continue; 22 112 } 23 113 Course course = new Course(name, type, access); 24 114 if (courseMap.containsKey(course.name)) { // 如果课程信息已经存在 25 115 continue; 26 116 } 27 117 courseMap.put(course.name, course); 28 118 } else { // 如果输入为学生成绩信息 29 119 String id = parts[0]; 30 120 String name = parts[1]; 31 121 String courseName = parts[2]; 32 122 int score1 = -1; // 平时成绩 33 123 int score2 = -1; // 期末成绩 34 124 try { 35 125 score1 = Integer.parseInt(parts[3]); 36 126 score2 = Integer.parseInt(parts[4]); 37 127 } catch (NumberFormatException e) { // 如果成绩信息格式不正确 38 128 System.out.println("wrong format"); 39 129 continue; 40 130 } 41 131 String classId = id.substring(0, 6); // 班级号 42 132 43 133 Course course = courseMap.get(courseName); 44 134 if (course == null) { // 如果指定课程不存在 45 135 System.out.println(id + " " + name + ":" + courseName + " does not exist"); 46 136 continue; 47 137 } 48 138 boolean added = course.addScore(score1); 49 139 added &= course.addScore(score2); 50 140 if (!added) { // 如果添加成绩失败 51 141 System.out.println(id + " " + name + ": access mode mismatch"); 52 142 continue; 53 143 } 54 144 55 145 Student student = studentMap.get(id); 56 146 if (student == null) { // 如果学生信息不存在,创建新的学生对象并添加到学生map中 57 147 student = new Student(id, name); 58 148 studentMap.put(id, student); 59 149 } 60 150 student.addCourse(course); // 添加选修课程 61 151 } 62 152 } catch (Exception e) { // 处理其他异常 63 153 System.out.println("wrong format"); 64 154 } 65 155 } 66 156 67 157 for (Student student : studentMap.values()) { // 输出每个学生的总成绩平均分 68 158 int avgScore = student.averageTotalScore(); 69 159 if (avgScore == -1) { 70 160 System.out.println(student.id + " " + student.name + ": no data"); 71 161 } else { 72 162 System.out.println(student.id + " " + student.name + ": " + avgScore); 73 163 } 74 164 } 75 165 } 76 166 }
这个主类是一个成绩管理系统的核心类,主要功能是读入输入信息并处理后输出结果。下面对这个类进行详细分析:
1. 属性:
- courseMap:保存所有课程信息的HashMap。
- studentMap:保存所有学生信息的TreeMap(按学号排序)。
2. 构造函数:
- 无。
3. 方法:
- main(String[] args):程序的入口方法。首先定义了两个Map变量,用于保存课程信息和学生信息。然后,使用Java中的Scanner类,循环读入所有输入信息。对于每一行输入信息,首先根据空格分隔符进行分割,并判断输入信息的格式是否符合要求。如果输入为课程信息,则根据输入信息创建一个新的课程对象,并加入到课程map中。如果输入为学生成绩信息,则根据输入信息创建一个新的学生对象,并将该学生添加到学生map中。在读取完所有输入信息后,进行遍历学生map,输出每个学生的总成绩平均分。
在这个主类中,我们使用了Scanner类来辅助读入输入信息,使用HashMap和TreeMap等Java集合框架中的功能,来存储和操作课程信息和学生信息。此外,我们还考虑了各种异常情况的处理,例如输入格式不正确、所指定的课程不存在、成绩信息不完整等等。这样的设计可以使程序更加健壮和鲁棒,能够应对各种意外情况。最后,我们还输出了每个学生的总成绩平均分,以供用户参考。
在写这个Java程序时,需要注意以下几点:
1. 在解析输入信息时,需要注意每个输入项的格式以及输入顺序,尤其是输入中可能存在的空格和换行符。
2. 在计算成绩平均分和总成绩平均分时,需要注意数据类型转换,将计算结果转换为整型,并确保数据精度不丢失。
3. 在处理异常情况时,需要先判断异常的类型,再输出相应的错误信息。
4. 在输出时,需要注意输出的格式,尤其是空格、换行符等细节。
在编写代码时,可以考虑将输入信息先保存在一个数据结构中,然后再进行处理和计算。可以使用HashMap或者类对象来保存信息。在计算平均分和总成绩平均分时,可以使用for循环遍历数据结构,并使用累加器计算总成绩和总成绩平均分。在处理异常情况时,可以使用try-catch块来捕捉异常,然后输出相应的错误信息。
编写这个Java程序可以帮助我们更好地理解数据结构和算法,并提高我们的编程能力和代码质量。在编写代码的过程中,需要注重细节和错误处理,保证程序的健壮性和稳定性。
7-1 容器-HashMap-检索
1 import java.util.*; 2 3 public class Main { 4 public static void main(String[] args) { 5 Scanner scanner = new Scanner(System.in); 6 HashMap<String, String> map = new HashMap<>(); 7 8 while (true) { 9 String input = scanner.nextLine().trim(); 10 if (input.equals("end")) { 11 break; 12 } 13 14 String[] parts = input.split(" "); 15 String id = parts[0]; 16 String name = parts[1]; 17 String score = parts[2]; 18 if (!map.containsKey(id)) { 19 String info = name + " " + score; 20 map.put(id, info); 21 } 22 } 23 24 String searchId = scanner.nextLine().trim(); 25 if (map.containsKey(searchId)) { 26 String info = map.get(searchId); 27 System.out.println(searchId + " " + info); 28 } else { 29 System.out.println("The student " + searchId + " does not exist"); 30 } 31 } 32 }
在写这个Java程序时,我们需要注意以下几点:
1. 输入数据格式的处理:我们需要按照一定的格式读取用户输入的数据,并将其分解为学生的ID、姓名和成绩三个部分。在这个程序中,我们使用了String类的trim()方法和split()方法来实现这个功能。
2. 数据结构的选择:我们需要选择合适的数据结构来存储学生的信息。在这个程序中,我们使用了HashMap类来存储学生的ID和姓名、成绩等信息。
3. 错误处理:在程序中,我们需要对一些可能出现的错误情况进行处理,比如输入格式不符合要求、学生ID重复等情况。
在优化这个程序时,我们可以考虑以下几点:
1. 输入数据格式的进一步处理:我们可以使用正则表达式等高级工具来进一步处理用户的输入数据,以确保输入数据的正确性。
2. 数据结构的优化:如果我们需要对学生的信息进行排序、筛选或统计等操作,那么我们需要选择合适的数据结构来支持这些操作。在这个程序中,我们可以考虑使用TreeMap类或者其他支持排序和查找操作的数据结构来存储学生信息。
3. 异常处理机制的加入:我们可以使用Java的异常处理机制来捕获和处理程序中可能出现的异常,以增强程序的健壮性和可靠性。
总结和心得:
在Java编程中,处理用户输入数据是一个非常常见的任务。我们需要选择合适的数据结构和算法来实现这个功能,同时需要注意代码的可读性、可维护性和可扩展性。在编写Java程序时,我们需要不断地学习和掌握新的技术和工具,以提高自己的编程能力和代码质量。
7-2 容器-HashMap-排序
1 import java.util.*; 2 3 public class Main { 4 public static void main(String[] args) { 5 Scanner scanner = new Scanner(System.in); 6 HashMap<String, String> map = new HashMap<>(); 7 8 while (true) { 9 String input = scanner.nextLine().trim(); 10 if (input.equals("end")) { 11 break; 12 } 13 14 String[] parts = input.split("\\s+"); 15 String id = parts[0]; 16 String name = parts[1]; 17 String score = parts[2]; 18 if (!map.containsKey(id)) { 19 String info = name + " " + score; 20 map.put(id, info); 21 } 22 } 23 24 ArrayList<String> sortedKeys = new ArrayList<>(map.keySet()); 25 Collections.sort(sortedKeys); 26 for (String key : sortedKeys) { 27 String info = map.get(key); 28 System.out.println(key + " " + info); 29 } 30 } 31 }
这个Java程序的主要功能是读取用户输入的学生信息(学号、姓名、成绩),并按照学号进行排序后输出。下面讲一下写这个程序时需要注意的点:
1. 输入格式的判断:在读取用户输入信息时,应该先判断输入格式是否符合要求。例如本程序中,输入信息应该由3个部分组成(学号、姓名、成绩),并进行了空格分割。如果输入格式不符合要求,应该输出错误提示信息并进行下一个输入信息的读取。
2. 数据存储的选择:对于本程序中的数据存储,我们选择了HashMap这个数据结构。在读取用户输入信息时,我们可以使用HashMap的key来存储学生的学号,value来存储学生的其他信息(姓名、成绩等)。这样做的好处是可以快速地查找是否已经存在该学生信息,而不用遍历所有已存储的信息。
3. 数据排序的实现:本程序需要对学生信息进行排序,按照学号的字典序进行排序。我们可以将HashMap中的key存储到一个ArrayList中,并使用Collections.sort方法对该ArrayList进行排序。然后再按照排好序的key值遍历HashMap,输出学生信息。
4. 注意空格和字符串截断:在读取用户输入信息时,我们需要注意字符串中可能出现的空格。为了避免空格的干扰,我们可以使用trim方法去掉字符串的首尾空格。另外,我们还需要注意在读取学生姓名时,可能出现姓名中间有空格的情况。为了正确读取学生姓名,我们可以使用String数组的部分截断方法来读取。
5. 代码重构和优化:在编写程序时,我们可以考虑将一些重复的代码封装成函数,提高程序的可读性和可维护性。此外,我们还可以对程序进行优化,例如使用Java8中的Stream API来简化代码。例如,对于排序部分的代码,我们可以使用Stream API中的sorted方法来代替Collections.sort方法。
总结和心得:
本程序虽然简单,但是实现了一些基本的Java编程知识和技巧。在编写程序时,需要注意输入格式的判断、数据存储的选择和数据排序的实现。同时,代码的重构和优化也是提高程序可读性和可维护性的重要手段。在编写Java程序时,还需要注重代码风格和命名规范,以便于后续的代码维护和开发。
7-3 课程成绩统计程序-2
public class Main { public static void main(String[] args) { // TODO Auto-generated method stub @SuppressWarnings("resource") Scanner sc=new Scanner(System.in); String data;//输入一行数据 String[] arr=new String[100]; data=sc.nextLine(); arr=data.split(" "); int flag3=0,input=0,i=0,j=0,k=0,konggenum=0,avsum=0,flag=0,flag1=0,avsumps=0,avsumqm=0,avsum1=0,avsum2=0,grade=0,index=0,qz=0,qm1=0; double gradesy=0; ArrayList<Choose> chooselist=new ArrayList<>(); ArrayList<Classroom> classroomlist=new ArrayList<>(); HashMap<Integer, Student> smap=new HashMap<Integer,Student>(); HashMap<String, Course> cmap=new HashMap<String,Course>(); HashMap<Integer, Integer> cjmap=new HashMap<Integer,Integer>(); Course course=new Course(); Classroom checkclass=new Classroom(); Student student=new Student(); Examgrade examgrade=new Examgrade(); Inspectgrade inspectgrade=new Inspectgrade(); Experiment experiment=new Experiment(); Choose choose=new Choose(); String coursename=null,classnum=null; double ps=0,qm=0,quanz=0; while(true) { if(data.equals("end")) break; else { konggenum=Jugde.kongge(data);//空格数 input=Jugde.input(arr,cmap,konggenum); switch(input) { case 1://加课程信息 { // if(arr.length==3) // { if(arr[1].equals("必修") && arr[2].equals("考察")) System.out.println(arr[0] + " : course type & access mode mismatch"); else if((arr[1].equals("实验")&&!arr[2].equals("实验"))||(!arr[1].equals("实验")&&arr[2].equals("实验"))) System.out.println(arr[0] + " : course type & access mode mismatch"); // else if(arr[1].equals("选修")&&!arr[2].equals("考试")&&!arr[2].equals("考察")) // System.out.println(arr[0]+" : course type & access mode mismatch"); else { if(!Jugde.checkcf(cmap,arr[0]))//没有重复的课 { if(arr[2].equals("实验")) { if(Integer.valueOf(arr[3])!=arr.length-4) { flag3=1; System.out.println(arr[0]+" : number of scores does not match"); } else { for(i=4;i<arr.length;i++) quanz+=Double.valueOf(arr[i]); if(quanz!=1.0) { flag3=1; System.out.println(arr[0]+" : weight value error"); } } quanz=0; } if(arr[2].equals("考试")) { if(arr.length-3!=2) { flag3=1; System.out.println(arr[0]+" : number of scores does not match"); } else { quanz+=Double.valueOf(arr[3]); quanz+=Double.valueOf(arr[4]); if(quanz/1.0!=0) { flag3=1; System.out.println(arr[0]+" : weight value error"); } } quanz=0; } // if(arr[1].equals("必修")&&!arr[2].equals("考试")) // { // quanz+=Double.valueOf(arr[2]); // quanz+=Double.valueOf(arr[3]); // if(quanz!=1.0) // { // flag3=1; // System.out.println(arr[0]+" : weight value error"); // } // quanz=0; // } if(flag3==0) cmap.put(arr[0],new Course(arr[0],arr[1],arr[2],data)); } } } // else if(arr.length==2) // { // if(arr[1].equals("选修")) // System.out.println(arr[0]+" : course type & access mode mismatch"); // else // { // if(!Jugde.checkcf(cmap,arr[0])&&arr.length==2)//没有重复的课 // cmap.put(arr[0],new Course(arr[0],arr[1],"考试",data)); // } // } break; // } case 2://加课程成绩信息 { if(!Jugde.getsingle(chooselist,arr[0]+arr[1]+arr[2]))//如果没有重复的成绩信息 { smap.put(Integer.valueOf(arr[0]),new Student(Integer.valueOf(arr[0]),arr[1])); checkclass=Jugde.checkclass(arr[0].substring(0,6),classroomlist);//查是否已有该班级 course=Jugde.checkcourse(arr[2],cmap);//查是否已有该课程 if(checkclass!=null)//如果找到该班号 { if(!Jugde.studentcf(classroomlist,arr[0])) { checkclass.code=Integer.valueOf(arr[0].substring(0,6));//班号 checkclass.list.add(new Student(Integer.valueOf(arr[0]),arr[1]));//在班级类中的学生数组加上学生 } } else//如果没找到该班号 classroomlist.add(new Classroom(Integer.valueOf(arr[0].substring(0,6)),new Student(Integer.valueOf(arr[0]),arr[1])));//在班级数组中加上该班 if(Jugde.checkcourse(arr[2],cmap)==null)//找不到该课程信息 { System.out.println(arr[2]+" does not exist");//课程不存在 flag=0; break; } else { if(Jugde.checkcourse(arr[2],cmap).assessmethod.equals("考试"))//考试成绩 if(arr.length==5)//考核方式与输入的成绩量匹配 { flag=1; if(Jugde.checkcourse(arr[2], cmap)!=null) course=Jugde.checkcourse(arr[2], cmap); qz=(int)(Double.valueOf(arr[3])*course.quanz.get(0)); qm1=(int)(Double.valueOf(arr[4])*course.quanz.get(1)); } if(Jugde.checkcourse(arr[2],cmap).assessmethod.equals("考察"))//考察成绩 if(arr.length==4)//考核方式与输入的成绩量匹配 flag=2; if(Jugde.checkcourse(arr[2],cmap).assessmethod.equals("实验"))//实验成绩 if(Jugde.checkassess(arr[2], arr.length-3, cmap)!=null)//考核方式与输入的成绩量匹配 { course=Jugde.checkassess(arr[2], arr.length-3, cmap); flag=3; for(i=0;i<arr.length-3;i++) gradesy+=Double.valueOf(arr[i+3])*course.quanz.get(i); // gradesy/=course.num; grade=(int)gradesy; } if(flag==0) { System.out.println(arr[0]+" "+arr[1]+" : access mode mismatch");//成绩数量和课程的考核方式不匹但课程存在 break; } } if(flag==1)//判断是考试课还是考察课 chooselist.add(new Choose(new Student(Integer.valueOf(arr[0]),arr[1]),Jugde.checkcourse(arr[2],cmap),new Examgrade(qz,qm1)));//在选课数组中加上选课 if(flag==2) chooselist.add(new Choose(new Student(Integer.valueOf(arr[0]),arr[1]),Jugde.checkcourse(arr[2],cmap),new Inspectgrade(Integer.valueOf(arr[3]))));//在选课数组中加上选课 if(flag==3) chooselist.add(new Choose(new Student(Integer.valueOf(arr[0]),arr[1]),Jugde.checkcourse(arr[2],cmap),new Experiment(grade)));//在选课数组中加上选课 flag=0; gradesy=0; grade=0; } break; } case 0://数据异常 { System.out.println("wrong format"); break; } } } data=sc.nextLine(); arr=data.split("\\s+"); } //调用sortHashMap()排序并返回新的集合 HashMap<Integer,Student> sort = Jugde.sortHashMap(smap);//将hash里面的学生学号进行排序 for(Entry<Integer,Student> entry:sort.entrySet()) { student=entry.getValue(); for(i=0,j=0;i<chooselist.size();i++) { choose=chooselist.get(i); if(choose.student.name.equals(student.name)&&choose.student.num==student.num) { j++; if(choose.grade instanceof Examgrade)//如果是考试课 { examgrade=(Examgrade)choose.grade; examgrade.getgrade(); } if(choose.grade instanceof Inspectgrade)//如果是考察课 { inspectgrade=(Inspectgrade)choose.grade; inspectgrade.getgrade(); } if(choose.grade instanceof Experiment)//如果是实验课 { experiment=(Experiment)choose.grade; experiment.getgrade(); } avsum+=choose.grade.sumgrade; flag1=1; } } if(flag1==0)//选课类中没有该学生 System.out.println(student.num+" "+student.name+" did not take any exams"); else { avsum/=j; cjmap.put(student.num,avsum); System.out.println(student.num+" "+student.name+" "+avsum); } avsum=0; flag1=0; } List<Entry<String,Course>> clist=new ArrayList<>(cmap.entrySet());//对课程排序 Collections.sort(clist,new Comparator<Entry<String,Course>>(){ @Override public int compare(Entry<String, Course> o1, Entry<String, Course> o2) { // TODO Auto-generated method stub Collator instance=Collator.getInstance(Locale.CHINA); return instance.compare(o1.getKey(),o2.getKey()); } }); for (i=0;i<clist.size();i++){ Entry<String, Course> ccmap=clist.get(i); coursename=ccmap.getKey(); for(j=0,k=0;j<chooselist.size();j++) { choose=chooselist.get(j); if(coursename.equals(choose.course.name))//如果找到选课里面的课程 { k++; if(choose.grade instanceof Examgrade)//如果是考试课 { examgrade=(Examgrade)choose.grade; avsumps+=examgrade.dailygrade; avsumqm+=examgrade.finalgrade; avsum1+=examgrade.sumgrade; flag1=2; } if(choose.grade instanceof Inspectgrade)//如果是考察课 { inspectgrade=(Inspectgrade)choose.grade; avsumqm+=inspectgrade.finalgrade; avsum1+=inspectgrade.sumgrade; flag1=3; } if(choose.grade instanceof Experiment)//如果是实验课 { experiment=(Experiment)choose.grade; avsumqm+=experiment.finalgrade; avsum1+=experiment.sumgrade; flag1=4; } } } if(flag1==0)//选课类中没有该课程 System.out.println(coursename+" has no grades yet"); else { if(flag1==2)//该课程为考试课 { ps=avsumps/10.0; qm=avsumqm/10.0; ps*=3; qm*=7; avsumps/=k; avsumqm/=k; avsum1/=k; System.out.println(coursename+" "+avsum1); } if(flag1==3)//该课程为考察课 { avsum1=avsumqm; avsumqm/=k; avsum1/=k; System.out.println(coursename+" "+avsum1); } if(flag1==4)//该课程为实验课 { avsum1=avsumqm; avsumqm/=k; avsum1/=k; System.out.println(coursename+" "+avsum1); } } avsumps=0; avsumqm=0; avsum1=0; flag1=0; } flag1=0; Collections.sort(classroomlist);//班级排序 for(i=0;i<classroomlist.size();i++) { for(Entry<Integer, Integer> entry:cjmap.entrySet()) { classnum=String.valueOf(entry.getKey()).substring(0,6); if(String.valueOf(classroomlist.get(i).code).equals(classnum)) { avsum+=entry.getValue(); flag1=1; } } for(j=0;j<classroomlist.get(i).list.size();j++) { student=classroomlist.get(i).list.get(j); for(k=0;k<chooselist.size();k++) { choose=chooselist.get(k); if(choose.student.name.equals(student.name)&&choose.student.num==student.num) index++; } } if(index==0||flag1==0) System.out.println(classroomlist.get(i).code+" has no grades yet"); else { avsum/=index; System.out.println(classroomlist.get(i).code+" "+avsum); } flag1=0; avsum=0; index=0; } } }
1 class Course{ 2 String name;//课程名称 3 String nature;//课程性质 4 String assessmethod;//考核方式 5 int num=0;//实验课成绩数量 6 ArrayList<Double> quanz=new ArrayList<>();//权重 7 Course(String name,String nature,String assessmethod,String data) { 8 String[] arr=new String[10]; 9 arr=data.split(" "); 10 this.name=name; 11 this.nature=nature; 12 this.assessmethod=assessmethod; 13 if(this.assessmethod.equals("考试")) 14 { 15 this.quanz.add(Double.valueOf(arr[3]));//期中权重 16 this.quanz.add(Double.valueOf(arr[4]));//期末权重 17 } 18 else if(this.assessmethod.equals("实验")) 19 { 20 for(int i=4;i<arr.length;i++) 21 this.quanz.add(Double.valueOf(arr[i])); 22 this.num=Integer.valueOf(arr[3]); 23 } 24 } 25 Course(){ 26 27 } 28 }
这个类是用于表示课程的类,包含了课程名称、课程性质、考核方式、实验课成绩数量以及权重等属性。
属性:
- name:课程名称。
- nature:课程性质。
- assessmethod:考核方式。
- num:实验课成绩数量。
- quanz:权重列表,用于存储考试或实验中各部分的权重。
方法:
- Course(String name,String nature,String assessmethod,String data):构造函数,用于初始化对象。
- Course():无参构造函数。
- 这个类没有提供任何get或set方法,因此属性都是默认的public访问权限。
在构造函数中,通过传入的参数进行初始化,其中通过字符串的split方法将传入的数据进行分割,然后根据不同的考核方式,将对应的权重加入到权重数组中。
值得注意的是,为了方便处理实验课成绩,该类还添加了一个num属性,用于记录实验课成绩的数量。
、这个类设计较为简洁,但是也充分考虑了不同考核方式的特点,为后续的课程管理系统提供了基础。同时,通过使用ArrayList来存储权重,也使得该类具有一定的扩展性,可以方便地添加新的权重。其实这个类还可以添加一些其他的属性和方法,例如添加一个描述课程大纲的方法,添加一个输出课程信息的方法等等,以使其更加完善。
1 class Student implements Comparable<Student>{ 2 int num;//学号 3 String name; 4 Student(int num,String name){ 5 this.num=num; 6 this.name=name; 7 } 8 Student(){ 9 10 } 11 @Override 12 public int compareTo(Student o) { 13 // TODO Auto-generated method stub 14 return Integer.compare(num,o.num); 15 }//姓名 16 }
这个类是用于表示学生的类,包含了学号和姓名等属性。
属性:
- num:学生的学号。
- name:学生的姓名。
方法:
- Student(int num,String name):构造函数,用于初始化学生对象。
- Student():无参构造函数。
- compareTo(Student o):实现了Comparable接口中的compareTo方法,用于比较两个学生对象的学号大小。该方法主要用于在TreeMap中按学号排序。
- 这个类没有提供任何get或set方法,因此属性都是默认的public访问权限。
在这个类中,我们主要用到了Comparable接口和compareTo方法,用于排序。通过实现Comparable接口,我们可以在TreeMap中按学号排序,方便后续的成绩管理。
这个类设计较为简单,但是也符合面向对象编程的思想,将学生对象的数据和操作进行了封装和分离,使代码更加易于维护。同时,通过使用Comparable接口和compareTo方法,还使得该类具有一定的扩展性,可以方便地针对不同的需求进行排序。
class Grade{ int sumgrade;//总成绩 } class Examgrade extends Grade{//考试课成绩 int dailygrade;//平时成绩 int finalgrade;//期末成绩 Fenxiang fenxiang=new Fenxiang(); void getgrade() { this.sumgrade=this.dailygrade+this.finalgrade; } Examgrade(int dailygrade,int finalgrade){ this.dailygrade=dailygrade; this.finalgrade=finalgrade; } Examgrade(){ } } class Inspectgrade extends Grade{//考察课成绩 int finalgrade;//期末成绩 void getgrade() { this.sumgrade=this.finalgrade; } Inspectgrade(int finalgrade){ this.finalgrade=finalgrade; } Inspectgrade(){ } } class Experiment extends Grade{//实验课成绩 int finalgrade;//期末成绩 Fenxiang fenxiang=new Fenxiang(); void getgrade() { this.sumgrade=this.finalgrade; } Experiment(int finalgrade){ this.finalgrade=finalgrade; } Experiment(){ } } class Fenxiang{//分项成绩类 int[] data;//成绩数值 double[] qz;//权重 }
这几个类是用于表示不同类型成绩的类,包括考试课成绩、考察课成绩和实验课成绩,以及辅助计算的分项成绩类。
`Grade`类:
属性:
- sumgrade:总成绩。
方法:
- 无。
`Examgrade`类:
属性:
- dailygrade:平时成绩。
- finalgrade:期末成绩。
- fenxiang:分项成绩对象。
方法:
- getgrade():计算总成绩。
- Examgrade(int dailygrade,int finalgrade):构造函数,用于初始化对象。
- Examgrade():无参构造函数。
`Inspectgrade`类:
属性:
- finalgrade:期末成绩。
方法:
- getgrade():计算总成绩。
- Inspectgrade(int finalgrade):构造函数,用于初始化对象。
- Inspectgrade():无参构造函数。
`Experiment`类:
属性:
- finalgrade:期末成绩。
- fenxiang:分项成绩对象。
方法:
- getgrade():计算总成绩。
- Experiment(int finalgrade):构造函数,用于初始化对象。
- Experiment():无参构造函数。
`Fenxiang`类:
属性:
- data:成绩数值数组。
- qz:权重数组。
方法:
- 无。
在这些类中,我们主要用到了继承和多态的思想,将不同类型的成绩封装在不同的类中。同时,通过在每个类中实现getgrade方法,计算总成绩,也使得这些类更加具有通用性。
值得注意的是,为了方便处理分项成绩,我们在`Examgrade`和`Experiment`类中添加了一个`Fenxiang`对象,用于存储分项成绩的数据和权重。
1 class Jugde{ 2 3 static Course checkassess(String name,int num,HashMap<String, Course> cmap) { 4 Set<String> keys=cmap.keySet(); 5 Course course=new Course(); 6 for(String key:keys) 7 { 8 course=cmap.get(key); 9 if(course.name.equals(name)&&course.num==num) 10 return course; 11 } 12 return null; 13 } 14 15 static boolean studentcf(ArrayList<Classroom> classroomlist,String arr) { 16 int num=0; 17 for(int i=0;i<classroomlist.size();i++) 18 { 19 for(int j=0;j<classroomlist.get(i).list.size();j++) 20 { 21 num=classroomlist.get(i).list.get(j).num; 22 if(Integer.valueOf(arr)==num) 23 return true; 24 } 25 } 26 return false; 27 } 28 static boolean getsingle(ArrayList<Choose> chooselist,String data) { 29 Choose choose; 30 String data1; 31 for(int i=0;i<chooselist.size();i++) 32 { 33 choose=chooselist.get(i); 34 data1=String.valueOf(choose.student.num)+choose.student.name+choose.course.name; 35 if(data1.equals(data)) 36 return true; 37 } 38 return false; 39 } 40 static boolean checkcf(HashMap<String, Course> cmap,String name) { 41 for(Map.Entry<String, Course> entry:cmap.entrySet()) 42 { 43 if(entry.getKey().equals(name)) 44 return true; 45 } 46 return false; 47 } 48 static HashMap<Integer, Student> sortHashMap(HashMap<Integer, Student> map) { 49 //从HashMap中恢复entry集合,得到全部的键值对集合 50 Set<Map.Entry<Integer,Student>> entries= map.entrySet(); 51 52 //将Set集合转为List集合,为了使用工具类的排序方法 53 List<Map.Entry<Integer,Student>> list= new ArrayList<Map.Entry<Integer,Student>>(entries); 54 55 //使用Collections工具类对list进行排序 56 //Collections.sort()是一个内置方法,仅排序值的列表。它在Collections类中重载。 57 58 Collections.sort(list, new Comparator<Map.Entry<Integer, Student>>() { 59 @Override 60 public int compare(Map.Entry<Integer, Student> o1, Map.Entry<Integer, Student> o2) { 61 //按照学号升序排序 62 return o1.getValue().num-o2.getValue().num; 63 //return o1.getValue().compareTo(o2.getValue()); 64 } 65 }); 66 67 //创建一个HashMap的子类LinkedHashMap集合 68 LinkedHashMap<Integer, Student> linkedHashMap= new LinkedHashMap<>(); 69 70 //将list中的数据存入LinkedHashMap中 71 for(Map.Entry<Integer,Student> entry:list){ 72 linkedHashMap.put(entry.getKey(),entry.getValue()); 73 } 74 return linkedHashMap; 75 } 76 77 @SuppressWarnings("unlikely-arg-type") 78 static Classroom checkclass(String arr,ArrayList<Classroom> classroomlist) { 79 int i=0; 80 for(i=0;i<classroomlist.size();i++) 81 { 82 if(classroomlist.get(i).code==Integer.valueOf(arr))//找到该班号 83 return classroomlist.get(i); 84 } 85 return null; 86 } 87 static Course checkcourse(String arr,HashMap<String, Course> cmap) { 88 if(cmap.get(arr)!=null) 89 return cmap.get(arr); 90 return null; 91 } 92 static boolean checkint(String arr) {//判断输入的数是否为正整数 93 if (arr!= null && !"".equals(arr.trim())){ 94 return arr.matches("^[0-9]*$"); 95 } else { 96 return false; 97 } 98 } 99 static int kongge(String data) {//统计有多少空格 100 char[] c=data.toCharArray(); 101 int i,konggenum=0; 102 for(i=0;i<data.length();i++) 103 { 104 if(data.charAt(i)==' ') 105 konggenum++; 106 } 107 return konggenum; 108 } 109 static int input(String[] arr,HashMap<String, Course> cmap,int konggenum) { 110 int flag=0; 111 if(arr[0].length()<=10&&(arr[1].equals("必修")||arr[1].equals("选修")||arr[1].equals("实验"))&&(arr[2].equals("考试")||arr[2].equals("考察")||arr[2].equals("实验"))) 112 { 113 return 1; 114 } 115 else 116 { 117 if((konggenum==4&&arr.length==5)&&arr[0].matches("^[0-9]{8}$")&&arr[1].length()<=10&&arr[2].length()<=10&&checkint(arr[3])&&checkint(arr[4])&&Integer.valueOf(arr[3])>=0&&Integer.valueOf(arr[3])<=100&&Integer.valueOf(arr[4])>=0&&Integer.valueOf(arr[4])<=100) 118 return 2; 119 if((konggenum==3&&arr.length==4)&&arr[0].matches("^[0-9]{8}$")&&arr[1].length()<=10&&arr[2].length()<=10&&checkint(arr[3])&&Integer.valueOf(arr[3])>=0&&Integer.valueOf(arr[3])<=100) 120 return 2; 121 if(arr[0].matches("^[0-9]{8}$")&&arr[1].length()<=10&&arr[2].length()<=10) 122 { 123 for(int i=4;i<arr.length;i++) 124 { 125 if(!(Integer.valueOf(arr[i])>=0&&Integer.valueOf(arr[i])<=100)) 126 flag=1; 127 } 128 if(flag==0) 129 return 2; 130 } 131 } 132 // if(konggenum==4&&arr.length==5&&arr[0].length()<=10&&(arr[1].equals("必修")||arr[1].equals("选修")||arr[1].equals("实验"))&&(arr[2].equals("考试")||arr[2].equals("考察")||arr[2].equals("实验")))//输入为课程信息选修或必修 133 // return 1; 134 // if(konggenum==2&&arr.length==3&&arr[0].length()<=10) 135 // return 1; 136 137 return 0;//格式错误以及其他信息异常如成绩超出范围等,均按格式错误处理,输出"wrong format" 138 } 139 }
这个类是一个工具类,主要用于编写一些判断输入数据格式是否正确的方法,包括判断学生和课程等信息的合法性,以及对输入的成绩进行有效性检查。这些方法都是静态方法,不需要实例化这个类就可以直接调用。
属性:无。
方法:
- checkassess(String name, int num, HashMap<String, Course> cmap):通过课程名称和编号,查找课程对象,返回课程对象。
- studentcf(ArrayList<Classroom> classroomlist, String arr):判断学生是否在班级中,返回布尔值。
- getsingle(ArrayList<Choose> chooselist, String data):判断学生是否已经选过该课程,返回布尔值。
- checkcf(HashMap<String, Course> cmap, String name):检查课程是否存在,返回布尔值。
- sortHashMap(HashMap<Integer, Student> map):按照学生学号从小到大排序,返回排序后的HashMap集合。
- checkclass(String arr, ArrayList<Classroom> classroomlist):通过班级编号,查找班级对象,返回班级对象。
- checkcourse(String arr, HashMap<String, Course> cmap):通过课程编号,查找课程对象,返回课程对象。
- checkint(String arr):判断输入的数是否为正整数,返回布尔值。
- kongge(String data):统计输入字符串中空格的数量,返回空格数量。
- input(String[] arr, HashMap<String, Course> cmap, int konggenum):输入数据检查,返回检查结果。
这个类的主要工作是对输入数据的格式进行检查,以确保输入的数据符合要求。其中,对于每一种类型的数据,都有不同的判断方法,并且判断方法的实现都比较简单,但是能够有效地避免一些不合法的数据输入。同时,这个类的方法都是静态方法,可以直接通过类名调用,方便快捷。
这个类的设计比较简单,但是非常实用。它能够有效地帮助我们保证输入数据的正确性,避免一些不必要的错误。同时,这个类的方法实现也非常简单,易于理解和维护。
7-4 动物发声模拟器(多态)
1 import java.util.*; 2 //动物发生模拟器. 请在下面的【】处添加代码。 3 public class Main { 4 public static void main(String[] args) { 5 Cat cat = new Cat(); 6 Dog dog = new Dog(); 7 Goat goat = new Goat(); 8 speak(cat); 9 speak(dog); 10 speak(goat); 11 } 12 static //定义静态方法speak() 13 void speak(Animal Animal){ 14 System.out.println(Animal.getAnimalClass()+"的叫声:"+Animal.shout()); 15 } 16 } 17 //定义抽象类Animal 18 abstract class Animal { 19 public abstract String getAnimalClass(); 20 public abstract String shout(); 21 } 22 //基于Animal类,定义猫类Cat,并重写两个抽象方法 23 class Dog extends Animal { 24 public String getAnimalClass() { 25 return "狗"; 26 } 27 public String shout() { 28 return "汪汪"; 29 } 30 } 31 class Cat extends Animal { 32 public String getAnimalClass() { 33 return "猫"; 34 } 35 public String shout() { 36 return "喵喵"; 37 } 38 } 39 class Goat extends Animal { 40 public String getAnimalClass() { 41 return "山羊"; 42 } 43 public String shout() { 44 return "咩咩"; 45 } 46 } 47 仔细分析这个代码,写出哪里需要改进,哪里能更简洁,最后打出心得
这段代码是一个简单的动物叫声模拟程序,主要用于展示Java中的继承和多态的特性。通过定义抽象类Animal和继承它的猫、狗和山羊类,实现了不同动物发出不同叫声的功能。
优点:
1. 采用了面向对象的思想,利用继承和多态,代码结构清晰,易于扩展和维护。
2. 通过抽象类Animal的定义,强制规范了子类的实现,提高了代码的可读性和可维护性。
3. 采用了静态方法speak(),不需要实例化Animal类,简化了代码。
缺点:
1. 代码较为简单,没有使用更多的设计模式或高级技术,无法体现出更高的复杂度和扩展性。
2. 只实现了不同动物发出不同叫声的功能,无法涉及更多的业务场景。
3. 没有使用异常处理机制,无法处理可能出现的异常情况,这可能导致程序的不稳定性。
心得:
通过这段代码,我深刻理解了Java中的继承和多态的特性。同时,我也意识到,一个简单的代码片段,也可以透彻地体现出面向对象的思想和设计原则。我会在以后的编程中,注重代码的可读性、可扩展性和可维护性。
7-1 容器-ArrayList-排序
1 import java.util.ArrayList; 2 import java.util.Collections; 3 import java.util.Comparator; 4 import java.util.Scanner; 5 6 class Student { 7 private String id; // 学号 8 private String name; // 姓名 9 private int mathScore; // 数学成绩 10 private int physicsScore; // 物理成绩 11 12 public Student(String id, String name, int mathScore, int physicsScore) { 13 this.id = id; 14 this.name = name; 15 this.mathScore = mathScore; 16 this.physicsScore = physicsScore; 17 } 18 19 public String getId() { 20 return id; 21 } 22 23 public String getName() { 24 return name; 25 } 26 27 public int getMathScore() { 28 return mathScore; 29 } 30 31 public int getPhysicsScore() { 32 return physicsScore; 33 } 34 35 // 计算数学和物理成绩之和 36 public int getTotalScore() { 37 return mathScore + physicsScore; 38 } 39 40 @Override 41 public String toString() { 42 return id + " " + name + " " + getTotalScore(); 43 } 44 } 45 46 public class Main { 47 public static void main(String[] args) { 48 Scanner scanner = new Scanner(System.in); 49 ArrayList<Student> students = new ArrayList<>(); 50 while (scanner.hasNext()) { 51 String line = scanner.nextLine(); 52 if (line.equals("end")) { 53 break; 54 } 55 String[] parts = line.split(" "); 56 String id = parts[0]; 57 String name = parts[1]; 58 int mathScore = Integer.parseInt(parts[2]); 59 int physicsScore = Integer.parseInt(parts[3]); 60 students.add(new Student(id, name, mathScore, physicsScore)); 61 } 62 63 // 按照数学成绩加物理成绩之和排序 64 Collections.sort(students, new Comparator<Student>() { 65 @Override 66 public int compare(Student s1, Student s2) { 67 if (s1.getTotalScore() == s2.getTotalScore()) { // 如果总成绩相同 68 return students.indexOf(s1) - students.indexOf(s2); // 按照输入先后顺序排序 69 } 70 return s1.getTotalScore() > s2.getTotalScore() ? -1 : 1; 71 } 72 }); 73 74 // 输出结果 75 for (Student student : students) { 76 System.out.println(student.getId() + " " + student.getName() + " " + student.getTotalScore()); 77 } 78 } 79 }
属性:
- String id:学号
- String name:姓名
- int mathScore:数学成绩
- int physicsScore:物理成绩
方法:
- public Student(String id, String name, int mathScore, int physicsScore):构造方法,创建一个学生对象,并初始化学号、姓名、数学成绩、物理成绩。
- public String getId():获取学号。
- public String getName():获取姓名。
- public int getMathScore():获取数学成绩。
- public int getPhysicsScore():获取物理成绩。
- public int getTotalScore():计算数学成绩和物理成绩之和。
- public String toString():将学生信息输出为字符串形式。
心得:
这段代码实现了对学生信息的输入和排序,其中,学生类定义了学号、姓名、数学成绩、物理成绩四个属性,以及相应的getter方法和toString方法。main方法中使用Scanner类从控制台读入学生信息,创建学生对象并将其添加到ArrayList中。然后使用Collections类对ArrayList进行排序,按照数学成绩加物理成绩之和进行排序,如果总成绩相同,按照输入先后顺序排序。最后输出排序后的结果。
这段代码的实现比较简单,但是涉及到了基本的Java语法和集合框架的使用。在实现过程中,需要注意使用Scanner类读取数据,使用ArrayList类存储学生信息,使用Collections类对ArrayList进行排序。同时,需要注意学生类中的属性和方法的定义,以及排序方法的实现。这段代码的实现比较典型,可以作为一个简单的练手项目。
7-3 课程成绩统计程序-2
public class Main { public static void main(String[] args) { @SuppressWarnings("resource") Scanner sc=new Scanner(System.in); String data;//输入一行数据 String[] arr=new String[100]; data=sc.nextLine(); arr=data.split(" "); int flag3=0,input=0,i=0,j=0,k=0,konggenum=0,avsum=0,flag=0,flag1=0,avsumps=0,avsumqm=0,avsum1=0,avsum2=0,grade=0,index=0,qz=0,qm1=0; double gradesy=0; ArrayList<Choose> chooselist=new ArrayList<>(); ArrayList<Classroom> classroomlist=new ArrayList<>(); HashMap<Integer, Student> smap=new HashMap<Integer,Student>(); HashMap<String, Course> cmap=new HashMap<String,Course>(); HashMap<Integer, Integer> cjmap=new HashMap<Integer,Integer>(); Course course=new Course(); Classroom checkclass=new Classroom(); Student student=new Student(); Examgrade examgrade=new Examgrade(); Inspectgrade inspectgrade=new Inspectgrade(); Experiment experiment=new Experiment(); Choose choose=new Choose(); String coursename=null,classnum=null; double ps=0,qm=0,quanz=0; while(true) { if(data.equals("end")) break; else { konggenum=Jugde.kongge(data);//空格数 input=Jugde.input(arr,cmap,konggenum); switch(input) { case 1://加课程信息 { if(arr[1].equals("必修") && arr[2].equals("考察")) System.out.println(arr[0] + " : course type & access mode mismatch"); else if((arr[1].equals("实验")&&!arr[2].equals("实验"))||(!arr[1].equals("实验")&&arr[2].equals("实验"))) System.out.println(arr[0] + " : course type & access mode mismatch"); else { if(!Jugde.checkcf(cmap,arr[0]))//没有重复的课 { if(arr[2].equals("实验")) { if(Integer.valueOf(arr[3])!=arr.length-4) { flag3=1; System.out.println(arr[0]+" : number of scores does not match"); } else { for(i=4;i<arr.length;i++) quanz+=Double.valueOf(arr[i]); if(quanz!=1.0) { flag3=1; System.out.println(arr[0]+" : weight value error"); } } quanz=0; } if(arr[2].equals("考试")) { if(arr.length-3!=2) { flag3=1; System.out.println(arr[0]+" : number of scores does not match"); } else { quanz+=Double.valueOf(arr[3]); quanz+=Double.valueOf(arr[4]); if(quanz/1.0!=0) { flag3=1; System.out.println(arr[0]+" : weight value error"); } } quanz=0; } if(flag3==0) cmap.put(arr[0],new Course(arr[0],arr[1],arr[2],data)); } } } break; case 2://加课程成绩信息 { if(!Jugde.getsingle(chooselist,arr[0]+arr[1]+arr[2]))//如果没有重复的成绩信息 { smap.put(Integer.valueOf(arr[0]),new Student(Integer.valueOf(arr[0]),arr[1])); checkclass=Jugde.checkclass(arr[0].substring(0,6),classroomlist);//查是否已有该班级 course=Jugde.checkcourse(arr[2],cmap);//查是否已有该课程 if(checkclass!=null)//如果找到该班号 { if(!Jugde.studentcf(classroomlist,arr[0])) { checkclass.code=Integer.valueOf(arr[0].substring(0,6));//班号 checkclass.list.add(new Student(Integer.valueOf(arr[0]),arr[1]));//在班级类中的学生数组加上学生 } } else//如果没找到该班号 classroomlist.add(new Classroom(Integer.valueOf(arr[0].substring(0,6)),new Student(Integer.valueOf(arr[0]),arr[1])));//在班级数组中加上该班 if(Jugde.checkcourse(arr[2],cmap)==null)//找不到该课程信息 { System.out.println(arr[2]+" does not exist");//课程不存在 flag=0; break; } else { if(Jugde.checkcourse(arr[2],cmap).assessmethod.equals("考试"))//考试成绩 if(arr.length==5)//考核方式与输入的成绩量匹配 { flag=1; if(Jugde.checkcourse(arr[2], cmap)!=null) course=Jugde.checkcourse(arr[2], cmap); qz=(int)(Double.valueOf(arr[3])*course.quanz.get(0)); qm1=(int)(Double.valueOf(arr[4])*course.quanz.get(1)); } if(Jugde.checkcourse(arr[2],cmap).assessmethod.equals("考察"))//考察成绩 if(arr.length==4)//考核方式与输入的成绩量匹配 flag=2; if(Jugde.checkcourse(arr[2],cmap).assessmethod.equals("实验"))//实验成绩 if(Jugde.checkassess(arr[2], arr.length-3, cmap)!=null)//考核方式与输入的成绩量匹配 { course=Jugde.checkassess(arr[2], arr.length-3, cmap); flag=3; for(i=0;i<arr.length-3;i++) gradesy+=Double.valueOf(arr[i+3])*course.quanz.get(i); grade=(int)gradesy; } if(flag==0) { System.out.println(arr[0]+" "+arr[1]+" : access mode mismatch");//成绩数量和课程的考核方式不匹但课程存在 break; } } if(flag==1)//判断是考试课还是考察课 chooselist.add(new Choose(new Student(Integer.valueOf(arr[0]),arr[1]),Jugde.checkcourse(arr[2],cmap),new Examgrade(qz,qm1)));//在选课数组中加上选课 if(flag==2) chooselist.add(new Choose(new Student(Integer.valueOf(arr[0]),arr[1]),Jugde.checkcourse(arr[2],cmap),new Inspectgrade(Integer.valueOf(arr[3]))));//在选课数组中加上选课 if(flag==3) chooselist.add(new Choose(new Student(Integer.valueOf(arr[0]),arr[1]),Jugde.checkcourse(arr[2],cmap),new Experiment(grade)));//在选课数组中加上选课 flag=0; gradesy=0; grade=0; } break; } case 0://数据异常 { System.out.println("wrong format"); break; } } } data=sc.nextLine(); arr=data.split("\\s+"); } //调用sortHashMap()排序并返回新的集合 HashMap<Integer,Student> sort = Jugde.sortHashMap(smap);//将hash里面的学生学号进行排序 for(Entry<Integer,Student> entry:sort.entrySet()) { student=entry.getValue(); for(i=0,j=0;i<chooselist.size();i++) { choose=chooselist.get(i); if(choose.student.name.equals(student.name)&&choose.student.num==student.num) { j++; if(choose.grade instanceof Examgrade)//如果是考试课 { examgrade=(Examgrade)choose.grade; examgrade.getgrade(); } if(choose.grade instanceof Inspectgrade)//如果是考察课 { inspectgrade=(Inspectgrade)choose.grade; inspectgrade.getgrade(); } if(choose.grade instanceof Experiment)//如果是实验课 { experiment=(Experiment)choose.grade; experiment.getgrade(); } avsum+=choose.grade.sumgrade; flag1=1; } } if(flag1==0)//选课类中没有该学生 System.out.println(student.num+" "+student.name+" did not take any exams"); else { avsum/=j; cjmap.put(student.num,avsum); System.out.println(student.num+" "+student.name+" "+avsum); } avsum=0; flag1=0; } List<Entry<String,Course>> clist=new ArrayList<>(cmap.entrySet());//对课程排序 Collections.sort(clist,new Comparator<Entry<String,Course>>(){ @Override public int compare(Entry<String, Course> o1, Entry<String, Course> o2) { // TODO Auto-generated method stub Collator instance=Collator.getInstance(Locale.CHINA); return instance.compare(o1.getKey(),o2.getKey()); } }); for (i=0;i<clist.size();i++){ Entry<String, Course> ccmap=clist.get(i); coursename=ccmap.getKey(); for(j=0,k=0;j<chooselist.size();j++) { choose=chooselist.get(j); if(coursename.equals(choose.course.name))//如果找到选课里面的课程 { k++; if(choose.grade instanceof Examgrade)//如果是考试课 { examgrade=(Examgrade)choose.grade; avsumps+=examgrade.dailygrade; avsumqm+=examgrade.finalgrade; avsum1+=examgrade.sumgrade; flag1=2; } if(choose.grade instanceof Inspectgrade)//如果是考察课 { inspectgrade=(Inspectgrade)choose.grade; avsumqm+=inspectgrade.finalgrade; avsum1+=inspectgrade.sumgrade; flag1=3; } if(choose.grade instanceof Experiment)//如果是实验课 { experiment=(Experiment)choose.grade; avsumqm+=experiment.finalgrade; avsum1+=experiment.sumgrade; flag1=4; } } } if(flag1==0)//选课类中没有该课程 System.out.println(coursename+" has no grades yet"); else { if(flag1==2)//该课程为考试课 { ps=avsumps/10.0; qm=avsumqm/10.0; ps*=3; qm*=7; avsumps/=k; avsumqm/=k; avsum1/=k; System.out.println(coursename+" "+avsum1); } if(flag1==3)//该课程为考察课 { avsum1=avsumqm; avsumqm/=k; avsum1/=k; System.out.println(coursename+" "+avsum1); } if(flag1==4)//该课程为实验课 { avsum1=avsumqm; avsumqm/=k; avsum1/=k; System.out.println(coursename+" "+avsum1); } } avsumps=0; avsumqm=0; avsum1=0; flag1=0; } flag1=0; Collections.sort(classroomlist);//班级排序 for(i=0;i<classroomlist.size();i++) { for(Entry<Integer, Integer> entry:cjmap.entrySet()) { classnum=String.valueOf(entry.getKey()).substring(0,6); if(String.valueOf(classroomlist.get(i).code).equals(classnum)) { avsum+=entry.getValue(); flag1=1; } } for(j=0;j<classroomlist.get(i).list.size();j++) { student=classroomlist.get(i).list.get(j); for(k=0;k<chooselist.size();k++) { choose=chooselist.get(k); if(choose.student.name.equals(student.name)&&choose.student.num==student.num) index++; } } if(index==0||flag1==0) System.out.println(classroomlist.get(i).code+" has no grades yet"); else { avsum/=index; System.out.println(classroomlist.get(i).code+" "+avsum); } flag1=0; avsum=0; index=0; } } }
1 class Course{ 2 String name;//课程名称 3 String nature;//课程性质 4 String assessmethod;//考核方式 5 int num=0;//实验课成绩数量 6 ArrayList<Double> quanz=new ArrayList<>();//权重 7 Course(String name,String nature,String assessmethod,String data) { 8 String[] arr=new String[10]; 9 arr=data.split(" "); 10 this.name=name; 11 this.nature=nature; 12 this.assessmethod=assessmethod; 13 if(this.assessmethod.equals("考试")) 14 { 15 this.quanz.add(Double.valueOf(arr[3]));//期中权重 16 this.quanz.add(Double.valueOf(arr[4]));//期末权重 17 } 18 else if(this.assessmethod.equals("实验")) 19 { 20 for(int i=4;i<arr.length;i++) 21 this.quanz.add(Double.valueOf(arr[i])); 22 this.num=Integer.valueOf(arr[3]); 23 } 24 } 25 Course(){ 26 27 } 28 }
这个类是用于表示课程的类,包含了课程名称、课程性质、考核方式、实验课成绩数量以及权重等属性。
属性:
- name:课程名称。
- nature:课程性质。
- assessmethod:考核方式。
- num:实验课成绩数量。
- quanz:权重列表,用于存储考试或实验中各部分的权重。
方法:
- Course(String name,String nature,String assessmethod,String data):构造函数,用于初始化对象。
- Course():无参构造函数。
- 这个类没有提供任何get或set方法,因此属性都是默认的public访问权限。
在构造函数中,通过传入的参数进行初始化,其中通过字符串的split方法将传入的数据进行分割,然后根据不同的考核方式,将对应的权重加入到权重数组中。
值得注意的是,为了方便处理实验课成绩,该类还添加了一个num属性,用于记录实验课成绩的数量。
、这个类设计较为简洁,但是也充分考虑了不同考核方式的特点,为后续的课程管理系统提供了基础。同时,通过使用ArrayList来存储权重,也使得该类具有一定的扩展性,可以方便地添加新的权重。其实这个类还可以添加一些其他的属性和方法,例如添加一个描述课程大纲的方法,添加一个输出课程信息的方法等等,以使其更加完善。
1 class Student implements Comparable<Student>{ 2 int num;//学号 3 String name; 4 Student(int num,String name){ 5 this.num=num; 6 this.name=name; 7 } 8 Student(){ 9 10 } 11 @Override 12 public int compareTo(Student o) { 13 // TODO Auto-generated method stub 14 return Integer.compare(num,o.num); 15 }//姓名 16 }
这个类是用于表示学生的类,包含了学号和姓名等属性。
属性:
- num:学生的学号。
- name:学生的姓名。
方法:
- Student(int num,String name):构造函数,用于初始化学生对象。
- Student():无参构造函数。
- compareTo(Student o):实现了Comparable接口中的compareTo方法,用于比较两个学生对象的学号大小。该方法主要用于在TreeMap中按学号排序。
- 这个类没有提供任何get或set方法,因此属性都是默认的public访问权限。
在这个类中,我们主要用到了Comparable接口和compareTo方法,用于排序。通过实现Comparable接口,我们可以在TreeMap中按学号排序,方便后续的成绩管理。
这个类设计较为简单,但是也符合面向对象编程的思想,将学生对象的数据和操作进行了封装和分离,使代码更加易于维护。同时,通过使用Comparable接口和compareTo方法,还使得该类具有一定的扩展性,可以方便地针对不同的需求进行排序。
class Grade{ int sumgrade;//总成绩 } class Examgrade extends Grade{//考试课成绩 int dailygrade;//平时成绩 int finalgrade;//期末成绩 Fenxiang fenxiang=new Fenxiang(); void getgrade() { this.sumgrade=this.dailygrade+this.finalgrade; } Examgrade(int dailygrade,int finalgrade){ this.dailygrade=dailygrade; this.finalgrade=finalgrade; } Examgrade(){ } } class Inspectgrade extends Grade{//考察课成绩 int finalgrade;//期末成绩 void getgrade() { this.sumgrade=this.finalgrade; } Inspectgrade(int finalgrade){ this.finalgrade=finalgrade; } Inspectgrade(){ } } class Experiment extends Grade{//实验课成绩 int finalgrade;//期末成绩 Fenxiang fenxiang=new Fenxiang(); void getgrade() { this.sumgrade=this.finalgrade; } Experiment(int finalgrade){ this.finalgrade=finalgrade; } Experiment(){ } } class Fenxiang{//分项成绩类 int[] data;//成绩数值 double[] qz;//权重 }
这几个类是用于表示不同类型成绩的类,包括考试课成绩、考察课成绩和实验课成绩,以及辅助计算的分项成绩类。
`Grade`类:
属性:
- sumgrade:总成绩。
方法:
- 无。
`Examgrade`类:
属性:
- dailygrade:平时成绩。
- finalgrade:期末成绩。
- fenxiang:分项成绩对象。
方法:
- getgrade():计算总成绩。
- Examgrade(int dailygrade,int finalgrade):构造函数,用于初始化对象。
- Examgrade():无参构造函数。
`Inspectgrade`类:
属性:
- finalgrade:期末成绩。
方法:
- getgrade():计算总成绩。
- Inspectgrade(int finalgrade):构造函数,用于初始化对象。
- Inspectgrade():无参构造函数。
`Experiment`类:
属性:
- finalgrade:期末成绩。
- fenxiang:分项成绩对象。
方法:
- getgrade():计算总成绩。
- Experiment(int finalgrade):构造函数,用于初始化对象。
- Experiment():无参构造函数。
`Fenxiang`类:
属性:
- data:成绩数值数组。
- qz:权重数组。
方法:
- 无。
在这些类中,我们主要用到了继承和多态的思想,将不同类型的成绩封装在不同的类中。同时,通过在每个类中实现getgrade方法,计算总成绩,也使得这些类更加具有通用性。
值得注意的是,为了方便处理分项成绩,我们在`Examgrade`和`Experiment`类中添加了一个`Fenxiang`对象,用于存储分项成绩的数据和权重。
1 class Jugde{ 2 3 static Course checkassess(String name,int num,HashMap<String, Course> cmap) { 4 Set<String> keys=cmap.keySet(); 5 Course course=new Course(); 6 for(String key:keys) 7 { 8 course=cmap.get(key); 9 if(course.name.equals(name)&&course.num==num) 10 return course; 11 } 12 return null; 13 } 14 15 static boolean studentcf(ArrayList<Classroom> classroomlist,String arr) { 16 int num=0; 17 for(int i=0;i<classroomlist.size();i++) 18 { 19 for(int j=0;j<classroomlist.get(i).list.size();j++) 20 { 21 num=classroomlist.get(i).list.get(j).num; 22 if(Integer.valueOf(arr)==num) 23 return true; 24 } 25 } 26 return false; 27 } 28 static boolean getsingle(ArrayList<Choose> chooselist,String data) { 29 Choose choose; 30 String data1; 31 for(int i=0;i<chooselist.size();i++) 32 { 33 choose=chooselist.get(i); 34 data1=String.valueOf(choose.student.num)+choose.student.name+choose.course.name; 35 if(data1.equals(data)) 36 return true; 37 } 38 return false; 39 } 40 static boolean checkcf(HashMap<String, Course> cmap,String name) { 41 for(Map.Entry<String, Course> entry:cmap.entrySet()) 42 { 43 if(entry.getKey().equals(name)) 44 return true; 45 } 46 return false; 47 } 48 static HashMap<Integer, Student> sortHashMap(HashMap<Integer, Student> map) { 49 //从HashMap中恢复entry集合,得到全部的键值对集合 50 Set<Map.Entry<Integer,Student>> entries= map.entrySet(); 51 52 //将Set集合转为List集合,为了使用工具类的排序方法 53 List<Map.Entry<Integer,Student>> list= new ArrayList<Map.Entry<Integer,Student>>(entries); 54 55 //使用Collections工具类对list进行排序 56 //Collections.sort()是一个内置方法,仅排序值的列表。它在Collections类中重载。 57 58 Collections.sort(list, new Comparator<Map.Entry<Integer, Student>>() { 59 @Override 60 public int compare(Map.Entry<Integer, Student> o1, Map.Entry<Integer, Student> o2) { 61 //按照学号升序排序 62 return o1.getValue().num-o2.getValue().num; 63 //return o1.getValue().compareTo(o2.getValue()); 64 } 65 }); 66 67 //创建一个HashMap的子类LinkedHashMap集合 68 LinkedHashMap<Integer, Student> linkedHashMap= new LinkedHashMap<>(); 69 70 //将list中的数据存入LinkedHashMap中 71 for(Map.Entry<Integer,Student> entry:list){ 72 linkedHashMap.put(entry.getKey(),entry.getValue()); 73 } 74 return linkedHashMap; 75 } 76 77 @SuppressWarnings("unlikely-arg-type") 78 static Classroom checkclass(String arr,ArrayList<Classroom> classroomlist) { 79 int i=0; 80 for(i=0;i<classroomlist.size();i++) 81 { 82 if(classroomlist.get(i).code==Integer.valueOf(arr))//找到该班号 83 return classroomlist.get(i); 84 } 85 return null; 86 } 87 static Course checkcourse(String arr,HashMap<String, Course> cmap) { 88 if(cmap.get(arr)!=null) 89 return cmap.get(arr); 90 return null; 91 } 92 static boolean checkint(String arr) {//判断输入的数是否为正整数 93 if (arr!= null && !"".equals(arr.trim())){ 94 return arr.matches("^[0-9]*$"); 95 } else { 96 return false; 97 } 98 } 99 static int kongge(String data) {//统计有多少空格 100 char[] c=data.toCharArray(); 101 int i,konggenum=0; 102 for(i=0;i<data.length();i++) 103 { 104 if(data.charAt(i)==' ') 105 konggenum++; 106 } 107 return konggenum; 108 } 109 static int input(String[] arr,HashMap<String, Course> cmap,int konggenum) { 110 int flag=0; 111 if(arr[0].length()<=10&&(arr[1].equals("必修")||arr[1].equals("选修")||arr[1].equals("实验"))&&(arr[2].equals("考试")||arr[2].equals("考察")||arr[2].equals("实验"))) 112 { 113 return 1; 114 } 115 else 116 { 117 if((konggenum==4&&arr.length==5)&&arr[0].matches("^[0-9]{8}$")&&arr[1].length()<=10&&arr[2].length()<=10&&checkint(arr[3])&&checkint(arr[4])&&Integer.valueOf(arr[3])>=0&&Integer.valueOf(arr[3])<=100&&Integer.valueOf(arr[4])>=0&&Integer.valueOf(arr[4])<=100) 118 return 2; 119 if((konggenum==3&&arr.length==4)&&arr[0].matches("^[0-9]{8}$")&&arr[1].length()<=10&&arr[2].length()<=10&&checkint(arr[3])&&Integer.valueOf(arr[3])>=0&&Integer.valueOf(arr[3])<=100) 120 return 2; 121 if(arr[0].matches("^[0-9]{8}$")&&arr[1].length()<=10&&arr[2].length()<=10) 122 { 123 for(int i=4;i<arr.length;i++) 124 { 125 if(!(Integer.valueOf(arr[i])>=0&&Integer.valueOf(arr[i])<=100)) 126 flag=1; 127 } 128 if(flag==0) 129 return 2; 130 } 131 } 132 // if(konggenum==4&&arr.length==5&&arr[0].length()<=10&&(arr[1].equals("必修")||arr[1].equals("选修")||arr[1].equals("实验"))&&(arr[2].equals("考试")||arr[2].equals("考察")||arr[2].equals("实验")))//输入为课程信息选修或必修 133 // return 1; 134 // if(konggenum==2&&arr.length==3&&arr[0].length()<=10) 135 // return 1; 136 137 return 0;//格式错误以及其他信息异常如成绩超出范围等,均按格式错误处理,输出"wrong format" 138 } 139 }
这个类是一个工具类,主要用于编写一些判断输入数据格式是否正确的方法,包括判断学生和课程等信息的合法性,以及对输入的成绩进行有效性检查。这些方法都是静态方法,不需要实例化这个类就可以直接调用。
属性:无。
方法:
- checkassess(String name, int num, HashMap<String, Course> cmap):通过课程名称和编号,查找课程对象,返回课程对象。
- studentcf(ArrayList<Classroom> classroomlist, String arr):判断学生是否在班级中,返回布尔值。
- getsingle(ArrayList<Choose> chooselist, String data):判断学生是否已经选过该课程,返回布尔值。
- checkcf(HashMap<String, Course> cmap, String name):检查课程是否存在,返回布尔值。
- sortHashMap(HashMap<Integer, Student> map):按照学生学号从小到大排序,返回排序后的HashMap集合。
- checkclass(String arr, ArrayList<Classroom> classroomlist):通过班级编号,查找班级对象,返回班级对象。
- checkcourse(String arr, HashMap<String, Course> cmap):通过课程编号,查找课程对象,返回课程对象。
- checkint(String arr):判断输入的数是否为正整数,返回布尔值。
- kongge(String data):统计输入字符串中空格的数量,返回空格数量。
- input(String[] arr, HashMap<String, Course> cmap, int konggenum):输入数据检查,返回检查结果。
这个类的主要工作是对输入数据的格式进行检查,以确保输入的数据符合要求。其中,对于每一种类型的数据,都有不同的判断方法,并且判断方法的实现都比较简单,但是能够有效地避免一些不合法的数据输入。同时,这个类的方法都是静态方法,可以直接通过类名调用,方便快捷。
总的来说,这个类的设计比较简单,但是非常实用。它能够有效地帮助我们保证输入数据的正确性,避免一些不必要的错误。同时,这个类的方法实现也非常简单,易于理解和维护。
1 import java.util.*; 2 3 public class Main { 4 public static void main(String[] args) { 5 Scanner scan = new Scanner(System.in); 6 int n = scan.nextInt(); 7 String[] carIds = new String[n]; 8 HashSet<String> carIdSet = new HashSet<>(); 9 for (int i = 0; i < n; i++) { 10 String carIdString = scan.next(); 11 if (!carIdSet.contains(carIdString)) { 12 carIds[i] = carIdString; 13 carIdSet.add(carIdString); 14 } 15 } 16 Comparator<String> com = new MyComparator(); 17 Arrays.sort(carIds, com); 18 19 boolean loop = true; 20 while (loop) { 21 String inputString = scan.next(); 22 switch (inputString) { 23 case "sort1": 24 for (String carId : carIds) { 25 if (carId != null) { 26 System.out.println(carId.substring(6, 10) + "-" + carId.substring(10, 12) + "-" + carId.substring(12, 14)); 27 } 28 } 29 break; 30 31 case "sort2": 32 for (String carId : carIds) { 33 if (carId != null) { 34 System.out.println(carId); 35 } 36 } 37 break; 38 39 default: 40 System.out.println("exit"); 41 loop = false; 42 break; 43 } 44 } 45 } 46 } 47 48 class MyComparator implements Comparator<String> { 49 50 @Override 51 public int compare(String o1, String o2) { 52 return o1.substring(6, 15).compareTo(o2.substring(6, 15)); 53 54 } 55 56 }
属性:
- 无
方法:
- main(String[] args):主方法,实现对车牌号的输入、去重、排序,以及根据输入的命令输出排序后的结果。
- compare(String o1, String o2):比较方法,实现了根据车牌号排序的逻辑。
心得:
这段代码实现了对车牌号的输入、去重、排序,以及根据输入的命令输出排序后的结果。其中,MyComparator类实现了Comparator接口,重写了compare方法,实现了根据车牌号排序的逻辑。主方法中使用Scanner类读取数据,去重后使用Arrays类对车牌号进行排序。然后根据输入的命令输出排序后的结果。
这段代码的实现比较简单,但是涉及到了基本的Java语法和集合框架、比较器的使用。在实现过程中,需要注意使用Scanner类读取数据,使用HashSet类去重,使用Arrays类对车牌号进行排序,以及根据输入的命令输出排序后的结果。同时,需要注意MyComparator类中compare方法的实现。这段代码的实现比较典型,对于初学Java的人来说,可以作为一个简单的练手项目。
7-4 jmu-Java-04面向对象进阶-03-接口-自定义接口ArrayIntegerStack
1 import java.util.Arrays; 2 import java.util.Scanner; 3 4 // 定义 IntegerStack 接口 5 interface IntegerStack { 6 // 入栈操作,如果 item 为 null 或者栈已满,则不入栈直接返回 null。如果插入成功,返回 item。 7 public Integer push(Integer item); 8 9 // 出栈操作,如果栈为空则返回 null。出栈时只移动栈顶指针,相应位置不置为 null。 10 public Integer pop(); 11 12 // 获得栈顶元素,如果栈为空则返回 null。 13 public Integer peek(); 14 15 // 判断栈是否为空,如果为空返回 true。 16 public boolean empty(); 17 18 // 返回栈中元素个数。 19 public int size(); 20 } 21 22 // 实现 IntegerStack 接口 23 class ArrayIntegerStack implements IntegerStack { 24 private Integer[] arr; // 存储栈中元素的数组 25 private int top = 0; // 栈顶指针 26 27 // 构造函数,初始化存储栈中元素的数组 28 public ArrayIntegerStack(int n) { 29 arr = new Integer[n]; 30 Arrays.fill(arr, null); 31 } 32 33 // 默认构造函数 34 public ArrayIntegerStack() {} 35 36 // 重写 toString 方法,返回存储栈中元素的数组 37 @Override 38 public String toString() { 39 return Arrays.toString(arr); 40 } 41 42 // 入栈操作,如果 item 为 null 或者栈已满,则不入栈直接返回 null。如果插入成功,返回 item。 43 @Override 44 public Integer push(Integer item) { 45 if (item == null || arr.length == top) { // 如果 item 为 null 或者栈已满,则不入栈直接返回 null。 46 return null; 47 } 48 arr[top++] = item; // 入栈操作 49 return item; // 返回 item 50 } 51 52 // 出栈操作,如果栈为空则返回 null。出栈时只移动栈顶指针,相应位置不置为 null。 53 @Override 54 public Integer pop() { 55 if (top == 0) { // 如果栈为空则返回 null。 56 return null; 57 } 58 return arr[--top]; // 出栈操作 59 } 60 61 // 获得栈顶元素,如果栈为空则返回 null。 62 @Override 63 public Integer peek() { 64 if (top == 0) { // 如果栈为空则返回 null。 65 return null; 66 } 67 return arr[top - 1]; // 返回栈顶元素 68 } 69 70 // 判断栈是否为空,如果为空返回 true。 71 @Override 72 public boolean empty() { 73 return top == 0; // 如果栈顶指针为 0,则说明栈为空,返回 true。 74 } 75 76 // 返回栈中元素个数。 77 @Override 78 public int size() { 79 return top; // 栈中元素个数即为栈顶指针所指位置 80 } 81 } 82 83 // 主函数类 84 public class Main { 85 public static void main(String[] args) { 86 Scanner scanner = new Scanner(System.in); 87 int n = scanner.nextInt(); // 栈的容量 88 ArrayIntegerStack ais = new ArrayIntegerStack(n); // 创建 ArrayIntegerStack 对象 89 int m = scanner.nextInt(); // 元素个数 90 while (m-- > 0) { // 循环入栈 91 int item = scanner.nextInt(); 92 System.out.println(ais.push(item)); // 输出入栈结果 93 } 94 System.out.println(ais.peek() + "," + ais.empty() + "," + ais.size()); // 输出栈顶元素、是否为空和元素个数 95 System.out.println(ais); // 输出存储栈中元素的数组 96 int x = scanner.nextInt(); // 出栈操作次数 97 while (x-- > 0) { // 循环出栈 98 System.out.println(ais.pop()); // 输出出栈结果 99 } 100 System.out.println(ais.peek() + "," + ais.empty() + "," + ais.size()); // 输出栈顶元素、是否为空和元素个数 101 System.out.println(ais); // 输出存储栈中元素的数组 102 } 103 }
属性:
- arr:存储栈中元素的数组
- top:栈顶指针
方法:
- ArrayIntegerStack(int n):构造函数,初始化存储栈中元素的数组
- ArrayIntegerStack():默认构造函数
- toString():重写 toString 方法,返回存储栈中元素的数组
- push(Integer item):入栈操作
- pop():出栈操作
- peek():获得栈顶元素
- empty():判断栈是否为空
- size():返回栈中元素个数
- main(String[] args):主方法,实现对 ArrayIntegerStack 的操作
心得:
这段代码实现了一个基于数组的栈结构,以及对其进行基本的入栈、出栈、获得栈顶元素、判断栈是否为空和返回栈中元素个数等操作。其中,ArrayIntegerStack类实现了IntegerStack接口,重写了该接口中的方法。主方法中使用Scanner类读取输入数据,然后进行了一系列的入栈、出栈等操作,并输出相关结果。
这段代码的实现比较简单,但是涉及到了基本的Java语法和面向对象编程的思想。在实现过程中,需要注意理解栈结构的特点,使用数组实现栈结构,以及重写IntegerStack接口中的方法。同时,需要注意栈空和栈满的判断,以及使用Scanner类读取输入数据。这段代码的实现比较典型,对于初学Java的人来说,可以作为一个简单的练手项目。
7-5 jmu-Java-03面向对象基础-05-覆盖
1 import java.util.*; 2 3 4 // 定义 PersonOverride 类 5 class PersonOverride { 6 private String name; // 姓名 7 private int age; // 年龄 8 private boolean gender; // 性别 9 10 // 构造函数,使用默认值初始化属性 11 public PersonOverride() { 12 this("default", 1, true); 13 } 14 15 // 构造函数,使用传入的参数初始化属性 16 public PersonOverride(String name, int age, boolean gender) { 17 this.name = name; 18 this.age = age; 19 this.gender = gender; 20 } 21 22 // 重写 toString 方法,返回对象的字符串表示形式 23 @Override 24 public String toString() { 25 return name + "-" + age + "-" + gender; 26 } 27 28 // 重写 hashCode 方法,计算对象的哈希值 29 @Override 30 public int hashCode() { 31 final int prime = 31; 32 int result = 1; 33 result = prime * result + age; 34 result = prime * result + (gender ? 1231 : 1237); 35 result = prime * result + ((name == null) ? 0 : name.hashCode()); 36 return result; 37 } 38 39 // 重写 equals 方法,判断两个对象是否相等 40 @Override 41 public boolean equals(Object obj) { 42 if (this == obj) 43 return true; 44 if (obj == null) 45 return false; 46 if (getClass() != obj.getClass()) 47 return false; 48 PersonOverride other = (PersonOverride) obj; 49 if (age != other.age) 50 return false; 51 if (gender != other.gender) 52 return false; 53 if (name == null) { 54 if (other.name != null) 55 return false; 56 } else if (!name.equals(other.name)) 57 return false; 58 return true; 59 } 60 } 61 62 // 主函数类 63 public class Main { 64 public static void main(String[] args) { 65 Scanner scanner = new Scanner(System.in); 66 67 // 输入 n1 和创建 person1 数组 68 int n1 = scanner.nextInt(); 69 PersonOverride[] person1 = new PersonOverride[n1]; 70 for (int i = 0; i < n1; i++) { 71 person1[i] = new PersonOverride(); 72 } 73 74 // 输入 n2 和创建 person2 数组 75 int n2 = scanner.nextInt(); 76 PersonOverride[] person2 = new PersonOverride[n2]; 77 HashSet<PersonOverride> set = new HashSet<>(); // 创建 HashSet 对象,用于去重 78 for (int i = 0; i < n2; i++) { 79 PersonOverride p = new PersonOverride(scanner.next(), scanner.nextInt(), scanner.nextBoolean()); 80 if (set.add(p)) { // 如果成功将 p 添加到 set 中,则说明没有重复元素 81 person2[i] = p; 82 } 83 } 84 scanner.close(); 85 86 // 输出 person1 数组中每个元素的字符串表示形式 87 for (int i = 0; i < n1; i++) { 88 System.out.println(person1[i].toString()); 89 } 90 91 // 输出 person2 数组中每个元素的字符串表示形式 92 for (int i = 0; i < n2; i++) { 93 if (person2[i] != null) { // 如果 person2[i] 不为 null,则说明该元素没有被去重 94 System.out.println(person2[i].toString()); 95 } 96 } 97 98 // 输出不重复元素个数 99 System.out.println(set.size()); 100 101 // 输出 PersonOverride 类的构造函数列表 102 System.out.println(Arrays.toString(PersonOverride.class.getConstructors())); 103 } 104 }
属性:
- name: String类型,表示姓名
- age: int类型,表示年龄
- gender: boolean类型,表示性别
方法:
- PersonOverride():构造函数,使用默认值初始化对象的属性
- PersonOverride(String name, int age, boolean gender):构造函数,使用传入的参数初始化对象的属性
- toString():重写 toString 方法,返回对象的字符串表示形式
- hashCode():重写 hashCode 方法,计算对象的哈希值
- equals(Object obj):重写 equals 方法,判断两个对象是否相等
- main(String[] args):主方法,实现了对 PersonOverride 类进行测试的逻辑
心得:
这段代码主要介绍了 Java 中如何重写 toString、hashCode 和 equals 方法,以及如何使用 HashSet 来去重。其中,PersonOverride 类重写了 toString、hashCode 和 equals 方法。重写 toString 方法时,使用了字符串拼接的方式返回对象的字符串表示形式。重写 hashCode 方法时,使用了一些常数和属性的值计算对象的哈希值。重写 equals 方法时,首先判断两个对象是否是同一个对象,如果是,则返回 true。然后判断两个对象的类型是否相同,如果不相同,则返回 false。最后,判断两个对象的属性值是否相等。在主方法中,使用 Scanner 类读取输入数据,创建 person1 和 person2 数组,并将 person2 数组中的重复元素去掉,最后分别输出这两个数组和不重复元素的个数。
这段代码的实现较简单,但是涉及到了 Java 中的一些基本概念,比如类、构造函数、属性、方法、重写、哈希值和去重等。在实现过程中,需要注意理解哈希值和 equals 的概念,以及如何重写这两个方法。同时,需要注意如何使用 HashSet 来去重。这段代码的实现比较典型,对于初学 Java 的人来说,可以作为一个简单的练手项目。
心得总结:
在学习了四个月的Java之后,我对这门语言有了更深入的理解和体会。Java不仅仅是一门编程语言,更是一种编程思想和方法。从最初的懵懂不解到现在逐渐领悟其精髓,我不断地学习、思考,并付诸实践。在今后的学习过程中,我会更加努力地去学习,做到真正的学以致用,不断提高自己的编程能力。
首先,学习Java的过程中,我深刻体会到了信心、恒心和毅力的重要性。当遇到困难和挫折时,我们不能轻言放弃,而是要坚定信念,勇往直前。只有通过不断地学习和实践,才能真正掌握这门语言的核心思想和技巧。
其次,我认为学习Java的过程应该是循环渐进、有始有终、按部就班、脚踏实地的。我们要从基础入手,逐步深入学习。在学习过程中,我们要注重实践,通过不断地编写代码和调试程序来提高自己的编程能力。同时,我们还要学会总结和反思,以便更好地掌握Java的编程思想。
此外,在学习Java的过程中,我也深刻体会到了编程思维的重要性。编程思维是一种解决问题的方法,它要求我们具备逻辑思维和抽象思维的能力,以及对问题的分析和解决的能力。我们要学会运用编程思维来分析问题、解决问题,从而不断提高自己的编程能力。
蔡老师一直秉承着认真教学,先学再教,让学生先通过作业了解课程大纲,再在课程中教授主要知识。以此达到学生自主学习的目的,使编写代码这样枯燥的工作变得更加有趣,自己也能比学其他课程时更加主动地去学习。每周测验使得我们在每周都能对上一周的自主学习内容做到更好地巩固,是检验上周自主学习效果的良好措施,可能刚开始会很不习惯,觉得每周都实验会使得有时没有时间学习其他课程,但过了几个周会发现自己已经习惯了这种方式,也督促自己学习更加高效,能够合理分配时间,在顾好其他工作、课程的同时,也能够认真准备每一次PTA测试。另外PTA分数排行榜能够使我们清楚的发现自己的学习效果与其他人相比是高是低,对自己要求的高低也可能造成不同的想法,虽然可能很多地方还和别人有很多差距,但能尽到自己的最大努力就好。
在今后的学习过程中,我会继续努力提高自己的编程能力,通过学习和实践来不断巩固和拓展Java的知识体系。同时,我还会积极参与各种项目实践,以便将所学知识应用于实际工作中。
总之,学习Java不仅仅是为了掌握一门编程语言,更是为了培养自己的编程思维和解决问题的能力。在未来的学习和工作中,我会更加努力地去学习、思考、实践,做到真正的学以致用,为实现自己的职业目标和人生理想不懈努力。