我遇到了一个问题,我必须组织一个值为列表的地图。我得到了一个名为学生的预先写好的课程。我必须编写一个返回地图的方法,如下所示:
Map<String, List<Student>> map;
键应该代表学生注册的课程,列表应该代表该课程的学生。我获得了一份学生名单,并且必须按照从最低到最高的GPA顺序将这些学生组织到地图中。
这是我给的学生班:
public static class Student {
private String name;
private int zip;
private Map<String, Double> grades;
public Student(String name, int zip) {
this.name = name;
this.zip = zip;
grades = new HashMap<String, Double>();
}
public void addGrade(String n, double d) {
grades.put(n, d);
}
public double getGrade(String n) {
return grades.get(n);
}
public Map<String, Double> getGrades(){
return grades;
}
public double getOverAllGrade() {
//To do as part of the test
double totalGrade = 0.0;
for (String grade : grades.keySet()) {
totalGrade += getGrade(grade);
}
double average = totalGrade / grades.size();
return average;
}
public int getZip() {
return zip;
}
public String getName() {
return name;
}
public boolean equals(Object o) {
Student s = (Student)o;
return zip == s.zip && name.equals(s.name);
}
public String toString() {
return name+" "+zip;
}
}
我已经尝试使用以下代码解决此问题(我已经包含了该方法的目的,以帮助消除混淆):
/**
* return a Map<String, List<Student>> of all the classes mapped
* to a List of Students in the order of their grades from lowest
* to highest
*
* @param students List<Student> the students in the school
* @return Map<String, List<Student>> {"class name":{Student1, Student2}, "class 2":{Student3, Student4"}}
*/
public static Map<String, List<Student>> organizeByClass(List<Student> students){
HashMap<String, List<Student>> map = new HashMap<String, List<Student>>();
for (Student student : students) {
for (String className : student.getGrades().keySet()) {
if (!map.keySet().contains(className)) { // If the class hasn't been added, it will be added
ArrayList<Student> studentsInClass = new ArrayList<Student>();
studentsInClass.add(student);
map.put(className, studentsInClass);
} else {
if (student.getOverAllGrade() < map.get(className).get(0).getOverAllGrade()) { // Sorts the students by GPA
map.get(className).add(0, student);
} else {
map.get(className).add(student);
}
}
}
}
return map;
}
这是我正在使用的测试用例(它正在使用JUnit库):
@Test
public void organizeByClassTest1() {
List<Student> col = new ArrayList<Student>();
col.add(createStudent("Bob", 12345));
col.add(createStudent("Earl", 67890));
col.add(createStudent("Roman", 12345));
col.add(createStudent("Victor", 45678));
col.add(createStudent("Nick", 67890));
col.add(createStudent("Aaron", 12345));
col.add(createStudent("Marissa", 45678));
col.add(createStudent("Enoch", 12345));
col.add(createStudent("Spencer", 12345));
col.add(createStudent("Britt", 45678));
Student s1 = createStudent("Justin", 67890);
col.add(s1);
Map<String, List<Student>> map1 = new HashMap<String, List<Student>>();
Random r = new Random();
List<Student> g1 = new ArrayList<Student>();
List<Student> h1 = new ArrayList<Student>();
List<Student> he1 = new ArrayList<Student>();
List<Student> cs1 = new ArrayList<Student>();
List<Student> p1 = new ArrayList<Student>();
map1.put("Geometry", g1);
map1.put("History", h1);
map1.put("Home Economics", he1);
map1.put("Physics", p1);
map1.put("Computer Science", cs1);
for (Student s : col) {
if (r.nextInt(5) > 0) {
s.addGrade("Geometry", r.nextDouble() * 4);
g1.add(s);
}
if (r.nextInt(5) > 0) {
s.addGrade("Computer Science", r.nextDouble() * 4);
cs1.add(s);
}
if (r.nextInt(5) > 0) {
s.addGrade("History", r.nextDouble() * 4);
h1.add(s);
}
if (r.nextInt(5) > 0) {
s.addGrade("Home Economics", r.nextDouble() * 4);
he1.add(s);
}
if (r.nextInt(5) > 0) {
s.addGrade("Physics", r.nextDouble() * 4);
p1.add(s);
}
}
Comparator<Student> c = new Comparator<Student>() {
public int compare(Student s1, Student s2) {
return (int) (s1.getOverAllGrade()-s2.getOverAllGrade());
}
};
Collections.sort(p1, c );
Collections.sort(he1, c );
Collections.sort(h1, c );
Collections.sort(cs1, c );
Collections.sort(g1, c );
Map<String,List<Student>> result = MappingAssessment.organizeByClass(col);
assertEquals(map1,result);
}
我不明白为什么我写的代码不正确。所有帮助表示赞赏。
谢谢,Steward。
答案 0 :(得分:1)
您没有正确排序学生,因为任何不是最高年级的学生都会被发送到列表的后面。
答案 1 :(得分:1)
您还应该使用LinkedList<Student>
而不是ArrayList<Student>
,因为每次遇到新学生时都会进行多次插入。每次学生列表已经存在于地图中(您的else {...}
块),您需要循环并对列表进行排序,而不是添加到列表的后面。