Comparable和Comparator用法小结

概述

Comparable 接口和 Comparator 接口都是用来比较两个对象。一个类实现 Comparable 表示该类的对象之间可以比较;Comparator 则表示一个比较器,传入两个对象,返回比较结果。

它们的代码定义:

public interface Comparable<T> {
    public int compareTo(T o);
}
@FunctionalInterface
public interface Comparator<T> {
    int compare(T o1, T o2);
    // ...
}

数组工具类和集合工具类中提供的 sort 排序方法就要求被排序的类实现 Comparable 接口或需要传入一个 Comparator 对象。

比较规则

compareTocompare 都是返回一个 int 类型值。

对于 o1.compareTo(o2)compare(o1, o2) ,返回不同 int 值时的意义:

  • 返回 0 ,表示两个值相等。
  • 返回 负数,表示 o1 会排在 o2 前面。即若是返回负数,o1、o2 位置不变
  • 返回 正数,表示 o1 会排在 o2 后面。即若是返回整数,o1、o2 位置交换

根据这 3 个点,在定义比较规则时,从 “返回负数表示两个值位置不变” 这个点入手:

  • 若是要按某个值升序排序,即返回负数的情况(o1,o2 位置不变)是 o1<o2 ,则应该 return o1-o2 。这样当返回负数时,o1、o2 是升序的,位置不用变;返回正数,表示 o1 大于 o2,此时是降序的,应该交换位置。
  • 而若是降序,返回负数的情况应是 o1>o2 ,则应该 return o2-o1 。同理。

示例:

定义类:

class A implements Comparable<A>{
    String name;
    Integer num;

    public A(String name, Integer num) {
        this.name = name;
        this.num = num;
    }

    // 排序时按 num 值递增进行
    @Override
    public int compareTo(A o) {
        // 递增(升序),对应上面所说的 return o1-o2
        return this.num - o.num;
    }

    @Override
    public String toString() { return "A{" + "name='" + name + '\'' + '}'; }
}

将 A 的多个对象加入 List ,用 sort 方法进行排序:

public static void main(String[] args) {
    A a1 = new A("a1", 1);
    A a2 = new A("a2", 3);
    A a3 = new A("a3", 2);

    List<A> list = new ArrayList<>();
    list.add(a1);
    list.add(a2);
    list.add(a3);
    System.out.println(list);
    Collections.sort(list);
    System.out.println(list);
}
输出:
before sort: [A{name='a1'}, A{name='a2'}, A{name='a3'}]
after sort: [A{name='a1'}, A{name='a3'}, A{name='a2'}]

再看一个复杂一点的例子,对一个 nx2 的数组按第一个值升序排序,若第一个值相等,按第二个值倒序排序

public static void main(String[] args) {
    int[][] array = new int[][]{
            {5,4},
            {6,4},
            {6,7},
            {2,3}
    };
    System.out.println("before sort: ");
    for (int[] ints : array) {
        System.out.println(Arrays.toString(ints));
    }

    // (这里使用 Lambda 表达式, o1、o2 是一个一维数组)
    // 第一个值相等时,第二个值倒序排序;否则第一个值升序排序
    Arrays.sort(array, (o1, o2)-> o1[0] == o2[0] ? o2[1] - o1[1] : o1[0] - o2[0]);

    System.out.println("\nafter sort: ");
    for (int[] ints : array) {
        System.out.println(Arrays.toString(ints));
    }
}
before sort: 
[5, 4]
[6, 4]
[6, 7]
[2, 3]

after sort: 
[2, 3]
[5, 4]
[6, 7]     
[6, 4]
posted @ 2021-03-29 11:02  bxxiao  阅读(187)  评论(0)    收藏  举报