Java使用多个参数对对象进行排序
我最近一直在努力更好地理解排序算法及其与不同类型输入的关系。目前,我正在开发一个学生管理程序,其中每个学生都有三个参数:姓氏、GPA和用户ID(String、double、int)。它们分别存储在一个学生类中,包含这三个参数,并且有几十个学生(该程序的一个关键功能是输入、删除和更新学生)
我的问题是:使用主要的排序算法(合并排序、快速排序等),按每个参数对学生列表进行排序的最佳方法是什么?例如,执行mergesort以按GPA排序列表的最佳方法是什么?或者使用快速排序按姓氏对列表进行排序
基本上我的问题归结为。。。如果这些对象没有三个参数,我可以对它们进行排序(编写mergesort对100个数字进行排序对我来说非常容易)。如何管理其他两个参数并确保排序后可以访问它们
# 1 楼答案
在Java中实现这一点的方法是使用不同的Comparators。然后你说:
或
这些比较器使用不同的字段来定义两个元素之间的顺序
例如,名称比较器可能是:
GPA比较程序可能是
# 2 楼答案
它实际上与排序数字没有什么不同,只是在这种情况下,您的“数字”是用户的三个字段,每个数字的值受每个字段的值的约束,字段的顺序决定排序的顺序
更具体地说,您有一个包含3个字段的元组:
<GPA, Last Name, User ID>
,假设您希望按GPA、姓氏和用户ID进行排序与219排序在139之上的方式相同(即,即使“十”位更低,“百”位也有更高的值),类似
<3.75, Jones, 5>
的元组将排序在<3.0, Adams, 2>
之上,因为“GPA位”(更重要)有更高的值,即使“姓氏位”更低(例如,琼斯比亚当斯“更低”)# 3 楼答案
这可能与主题无关,但是如果您想尝试一些很酷的东西,JDK 8 Lambda Preview提供了一些很酷的方法来使用Lamda expressions and method references定义比较器
假设我们有一门课:
然后是它们的集合:
或者使用方法引用,假设绝地有一个类似于比较器的方法(相同的签名)
可按如下方式使用,通过使用方法参考生成比较器:
# 4 楼答案
我建议在
Student
类中实现Comparable
接口,如下所示然后使用内置的排序,如
或者您不能实现
Comparable
并设计自己的比较器然后可以使用另一种
Collection's
排序方法# 5 楼答案
使用多个比较器
# 6 楼答案
实现这一点的典型方法是对接受^{} 的任何类型编写通用排序算法,然后编写不同的
Comparator
按不同字段排序