java 使用Comparable接口实现自定义比较
程序员文章站
2022-05-23 18:04:37
...
最近写水题,很多都是要实现:按A字段降序排序,若相同则按B字段升序排序。利用JAVA的Comparable接口可以很轻易的实现。很多博客在写重写compareTo方法时,都只是说 "大于返回1 小于返回-1 相等返回0",这样的描述看得让人不知所云,自己亲自实践后,发现这些博客写的都有瑕疵,于是自己写下这篇博客,以后方便查阅。可能有些人没基础,所以我会从简单的讲起。
1、使用哪个方法实现排序?
在JAVA中可以通过下面两种自带方法实现排序 :
//对数组排序
Arrays.sort(待排序数组)
//对列表排序
Collections.sort(待排序列表);
实际上我们查看Collections.sort()的源码可以发现,它也是复用了Arrays.sort()函数(毕竟数组列表可以相互转化):
default void sort(Comparator<? super E> c) {
Object[] a = this.toArray(); //先转化为数组
Arrays.sort(a, (Comparator) c); //再排序
ListIterator<E> i = this.listIterator();
for (Object e : a) {
i.next();
i.set((E) e);
}
}
2、对要排序的对象数组/列表里的对象要有什么要求?
想要排序,必须要先实现Comparable接口,并重写compareTo方法。可以查看Arrays.sort()的源码,其就是通用将对像转换成Comparable,再利用compareTo 函数来判断对象排序的先后顺序。
class Test implements Comparable<Test>{
@Override
public int compareTo(Test another) {
......
}
}
3、如何自定义升/降序?
通过实现compareTo方法,我们可以比较灵活的定制按某某字段升序或降序,甚至可以实现按A降序,A相同时,按B升序的需求。显然,compareTo返回的是个int值,且在源码中,Arrays.sort()使用compareTo函数,只关心其符号:
1、小于0 2、大于0 3、等于0
在接下来的代码里,小于0用-1表示,大于0用1表示。
如何定义返回值?要看你是升序还是降序:
- 升序排序
大于 another对象 返回1
小于 another对象 返回-1
等于another对象 返回0 - 降序排序
大于 another对象 返回-1
小于 another对象 返回1
等于another对象 返回0
举例:现有Test类,其含有(int)score、(String)name两个字段,现要求按score降序排序;若score相等,则按name升序排序。
class Test implements Comparable<Test>{
int score;
String name;
public Test(int score, String name) {
this.score = score;
this.name = name;
}
@Override
public int compareTo(Test another) {
//score按降序
if (this.score > another.score){
return -1;
}else if (this.score < another.score){
return 1;
}else {//成绩相等
//按名字升序
if (this.name.compareTo(another.name) > 0){
return 1;
}else if (this.name.compareTo(another.name) < 0){
return -1;
}else {//名字相等
return 1;
}
}
}
@Override
public String toString() {
return "Test{" +
"score=" + score +
", name='" + name + '\'' +
'}';
}
}
测试:
public static void main(String[] args) {
Test[] tests = new Test[]{new Test(100,"b"),new Test(100,"a"),new Test(95,"c")};
Arrays.sort(tests);
for (int i = 0; i < tests.length; i++) {
System.out.println(tests[i]);
}
}
//测试结果
Test{score=100, name='a'}
Test{score=100, name='b'}
Test{score=95, name='c'}
推荐阅读
-
java自定义注解接口实现方案
-
Map集合的遍历方式以及TreeMap集合保存自定义对象实现比较的Comparable和Comparator两种方式
-
【JAVA】用Comparable接口学生的成绩做降序排序!请正确指定泛型;用Comparator实现按照姓名排序,请正确指定泛型!
-
ASP.NET Core 使用 JWT 自定义角色/策略授权需要实现的接口
-
java比较器 --- 使用Comparator实现定制排序
-
JAVA--set接口及其实现类的使用
-
ASP.NET Core使用JWT自定义角色并实现策略授权需要的接口
-
Java比较器——Comparable接口和Comparator接口
-
JAVA:使用阿里云短信接口实现短信验证码的发送(详解)
-
java-如何在不使用比较器和比较器接口的情况下对地图进行排序?如何编写自定义排序?