欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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'}