最近接到一个需求,要求对成绩单的成绩进行排序。不是按照成绩排序,而是按照课程类别和上课的时间进行排序。我首先想到的是双循环,但是我认为这样的话if-else要写到猴年马月。
之后我开始回忆以前的数据结构了,不论是二分法还是快排,他们分明比较的都是数字大小啊,字符串虽然可以比较,但是现在课程的排序是人为自定义的,我怎么比较呢?
二、问题:根据现在遇到的情况我就认为,想要排序必然要把字符串转换成数字,毕竟排序都是数字的,那么只有这样才能够直接比较。因此很自然的需要创建一个HashMap存放课程类别和它对应的大小。
成绩单长这样。
我这里的课程类别是一个对象,因为课程类别里面有一级学科二级学科这样,不过这是业务知识不重要,因此直接开始讲我的解决方案。在实际业务当中,数据还有老成绩和新成绩的说法,所以判断的地方非常多,有一点点小复杂。
四、代码使用的是Collections下的sort方法,传入你需要排序的List以及排序方法。
//自定义排序1 Collections.sort(list, new Comparator() { @Override public int compare(Student o1, Student o2) { return o1.getId() - o2.getId(); } });
前面提到过,既然是自定义排序,那么一定要对排序的东西事先定义好排序大小。
//为给课程排序,自定义排序规则,key是course_category的id,value是排名
private static Map zsCourseSortMap = new HashMap<>();//专硕
private static Map xsCourseSortMap = new HashMap<>();//学硕
static {
xsCourseSortMap.put(1249L,0);//学位公共课(必修)
xsCourseSortMap.put(18L,1);//学位基础课(必修)
xsCourseSortMap.put(19L,2);//学位专业课(必修)
xsCourseSortMap.put(20L,3);//学位专业课(选修)
xsCourseSortMap.put(21L,4);//跨学科或跨专业课程(选修)
xsCourseSortMap.put(23L,5);//公共选修课
xsCourseSortMap.put(-1L,100);//其它
zsCourseSortMap.put(1254L,0);//公共课 必修
zsCourseSortMap.put(1265L,0);//公共课 通识
zsCourseSortMap.put(18L,1);//学位基础课
zsCourseSortMap.put(670L,2);//专业必修课
zsCourseSortMap.put(671L,3);//专业选修课
zsCourseSortMap.put(672L,4);//专业实践
zsCourseSortMap.put(-1L,100);//
}
解释一下,这里的Key是课程类别对象的id,value是我自定义的大小,到时候只需要判断类别的id就能判断是哪一门课类别,之所以不直接存对象是我觉得这里new对象是一件很麻烦的事情,如果还要从数据库中一个个找出来存好,或许增加了不必要的开销。使用static是因为这些资源是亘古不变的,不随对象的变化而变化。
这里介绍一下传入的成绩列表。传进去的每一个成绩实际上是一个Map而不是Score对象。因为业务上表要达到范式要求,表的属性不能要啥都有啥,很多时候是精简的,Score本身可能并不存课程类别之类的。因此实际上获取的数据是已经封装好的Map格式
List
private void sortScoreListByCategory(List
五、代码解释
根据最上面的格式,sort传进去一个List和comparator。degreeTypeMap是最前面第二个自定义的Map排序规则,要用到。
compare里面其实就是传进去两个List里存放的两个随意对象。因为本质是两两比较。
严谨点需要先判断,Map里取出的courseCategory(课程类别)能不能转型成课程类别,如果不能则说明是老数据(业务问题),从数据库中找出这个课程类别对象。那么至此就获取了需要比较的这两个对象的课程类别。
核心: 关键就是下面的如果课程类别的id不相等则说明要比较,然后从自定义的Map中获取这门课程类别的排序值,但是这里需要多一个判断,因为自定义排序可能有其他的类型,如果没有找到这门课的课程类别说明是其它,按照其它处理。
获取两门课的排序值以后,直接对他门进行.compareTo就行了当然相减也可以。
如果课程类别的id一样则再判断他们课程的学年就行了,这里因为学年是时间字符串,可以直接比较。
升序降序 :
@Override
public int compareTo(Student o1, Student o2) {
//降序
//return o1.compareTo(o2);
//升序
return o2.compareTo(o1);
}
根据第一个参数小于、等于或大于第二个参数分别返回负整数、零或正整数
降序就是由下往上是从大到小。
暂时先这样写



