【Java】Comparable和Comparator

今天来分析一下Comparable和Comparator的区别,以及源码的解读。

Comparable

  • 源码:
public interface Comparable {
 public int compareTo(T o);
}

我们可以发现Comparable只是一个简单的泛型接口,内部含有一个compareTo接口。
根据接口的说明可知:

  1. 实现了这个接口的集合(或者数组)可以通过使用Collections.sort()(或者Arrays.sort())进行排序
  2. 实现了这个接口的对象,并重写了CompareTo()方法,可以无需Comparator比较器按照key值进行排序
  • 使用方法:
@Data
@NoArgsConstructor
@AllArgsConstructor
class Person implements Comparable {

    private String name;
    private Integer age;
    
    @Override
    public int compareTo(Person o) {
        return this.getAge().compareTo(o.getAge());
    }
}

public static void main(String[] args) {
        Person p1 = new Person("stalary", 21);
        Person p3 = new Person("hawk", 19);
        Person p2 = new Person("claire", 20);
        List list = new ArrayList<>();
        list.add(p1);
        list.add(p2);
        list.add(p3);
        Collections.sort(list);
        System.out.println(list);
    }
  1. 实现了将对象集合按年龄的升序排序,当想实现降序排序的时候,只需要将this和p的顺序交换
  2. compareTo()会返回一个整数,小于0代表小于,等于0代表等于,大于0代表大于,当返回正数时,即交换两个数,完成比较

Comparator

当我们想要比较的对象没有实现Comparable接口时,即没发使用上述方法进行比较,这时可以使用Comparator来进行比较。

下面先来看一下Comparator的源码

@FunctionalInterface
public interface Comparator {

    int compare(T o1, T o2);
    
    boolean equals(Object obj);
    
    default Comparator reversed() {
        return Collections.reverseOrder(this);
    }
    default Comparator thenComparing(Comparator other) {
        Objects.requireNonNull(other);
        return (Comparator & Serializable) (c1, c2) -> {
            int res = compare(c1, c2);
            return (res != 0) ? res : other.compare(c1, c2);
        };
    }
    default Comparator thenComparingInt(ToIntFunction keyExtractor) {
        return thenComparing(comparingInt(keyExtractor));
    }

  1. 我们排序时需要实现的方法是compare。
  2. equals在排序时没有用到,是从Object继承来的默认实现
  3. 后面省略了一些default的方法,这些方法都是jdk1.8中针对lambda实现的默认方法
  • 使用方法:
List peopleList = new ArrayList<>();
        peopleList.addAll(Arrays.asList(new People("stalary", 21),new People("claire", 20),new People("hawk", 19)));
        Collections.sort(peopleList, new PeopleComparator());
        
        @Data
@NoArgsConstructor
@AllArgsConstructor
class People {

    private String name;
    private Integer age;

}

@Data
@NoArgsConstructor
class PeopleComparator implements Comparator {


    @Override
    public int compare(People o1, People o2) {
        return o1.getAge() - o2.getAge();
    }

}

在jdk1.8中我们可以这样进行排序

peopleList.sort(Comparator.comparing(People::getAge));

当想要升序排序时,我们可以修改比较器中的compare或者直接调用reversed方法(1.8中实现的默认方法)

还可以在比较时写一个匿名内部类的比较器进行比较,但使用lambda更加方便,所以不推荐使用。

总结

总体来看Comparator更加灵活,可以不需要对象去继承一个接口,而且在1.8引入了lambda以后使用更加方便

你可能感兴趣的:(【Java】Comparable和Comparator)