如何按自定义部门顺序高效排序Student对象列表?
高性能自定义多字段排序方案(Java实现)
嘿,针对你这个按自定义部门顺序+id排序的需求,我给你一个既省空间又高效的解决方案,完美避开你之前遇到的问题!
核心思路
咱们不用分组合并(太占空间),也不用局限于Comparable的单字段排序,而是用自定义Comparator结合优先级映射表来实现:
- 先把自定义的部门顺序转换成一个
Map<String, Integer>,每个部门对应它的优先级索引(比如"Maths"对应0,"Science"对应1,"English"对应2),这样查找优先级的时间是O(1),超快。 - 然后实现一个
Comparator<Student>,排序逻辑分两步:- 先比较两个学生的部门优先级,优先级小的排前面
- 如果部门优先级相同(也就是同一个部门),再按id从小到大排序
完整代码实现
首先,给你的Student类加上getter方法(排序需要读取字段值):
class Student { private int id; private String name; private String department; // 构造方法 public Student(int id, String name, String department) { this.id = id; this.name = name; this.department = department; } // Getter方法 public int getId() { return id; } public String getDepartment() { return department; } // 重写toString方便打印结果 @Override public String toString() { return "{\"id\": " + id + ", \"name\": \"" + name + "\", \"department\": \"" + department + "\"}"; } }
然后是排序的核心逻辑:
import java.util.*; public class StudentSorter { public static void main(String[] args) { // 自定义部门顺序 List<String> deptOrder = Arrays.asList("Maths", "Science", "English"); // 构建部门优先级映射表 Map<String, Integer> deptPriority = new HashMap<>(); for (int i = 0; i < deptOrder.size(); i++) { deptPriority.put(deptOrder.get(i), i); } // 示例学生列表 List<Student> students = Arrays.asList( new Student(1, "some name 1", "English"), new Student(2, "some name 2", "Maths"), new Student(3, "some name 3", "Science") ); // 自定义排序器 Comparator<Student> studentComparator = (s1, s2) -> { // 先比较部门优先级 int deptCompare = Integer.compare( deptPriority.get(s1.getDepartment()), deptPriority.get(s2.getDepartment()) ); // 如果部门相同,再比较id if (deptCompare == 0) { return Integer.compare(s1.getId(), s2.getId()); } return deptCompare; }; // 排序(注意:如果是不可变列表,需要先转成可变列表再排序) List<Student> sortedStudents = new ArrayList<>(students); sortedStudents.sort(studentComparator); // 打印结果 System.out.println("["); for (int i = 0; i < sortedStudents.size(); i++) { System.out.println(" " + sortedStudents.get(i) + (i == sortedStudents.size()-1 ? "" : ",")); } System.out.println("]"); } }
为什么这个方案高性能?
- 空间效率:只需要一个大小等于部门种类数的映射表,空间复杂度是O(k)(k是自定义顺序里的部门数量),比分组合并的O(n)空间节省太多。
- 时间效率:排序本身是O(n log n)的标准排序时间,而每次比较操作都是O(1)的(映射表查找+整数比较),整体效率拉满。
- 灵活性:如果之后要调整排序规则,比如先id再部门,或者加其他字段排序,直接修改
Comparator的逻辑就行,非常灵活。
运行结果
执行上面的代码,会输出你期望的结果:
[ {"id": 2, "name": "some name 2", "department": "Maths"}, {"id": 3, "name": "some name 3", "department": "Science"}, {"id": 1, "name": "some name 1", "department": "English"} ]
内容的提问来源于stack exchange,提问作者yashjain12yj
相关产品推荐
相关产品推荐

