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

Java源码系列(1):Comparable和Comparator的区别

程序员文章站 2022-05-23 14:17:24
...

在将Comparable和Comparator区别之前,先补充一个知识点。
先看代码:

public class Person<T> {
  private T id;

  public T getId() {
    return id;
  }

  public void setId(T id) {
    this.id = id;
  }
}

 

public class test {
  public  static void main(String[] args){
    //id为String类型
    Person<String> person1=new Person<>();
    person1.setId("00001");
    System.out.println(person1.getId());
    //id为Integer类型
    Person<Integer> person2=new Person<>();
    //person2.setId("1");//错误,因为id为Integer类型
    person2.setId(1);
    System.out.println(person2.getId());
  }
}

结果如下:

Java源码系列(1):Comparable和Comparator的区别

解释:此处的T为泛型,是Java1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这样的好处是所有的强制类型转化都是自动和隐式的,提高了代码的重用率,比如Map<K,V>就是使用这样的方式。

先讲Comparable:
comparable:是一个接口,只有一个方法。

public interface Comparable<T>{
    public int compareTo(T o);
}


后讲Comparator:

public interface Comparator<T> {
    int compare(T o1, T o2);
    boolean equals(Object obj);
}


例子1:(对Long类型的List排序

public class test {
  public  static void main(String[] args){
    List<Long> list=new ArrayList<>();
    list.add(1L);
    list.add(12L);
    list.add(3L);
    list.add(4L);
    //1.第一种方法:使用工具类排序
    Collections.sort(list);
    //2.第二种方法:使用Comparator
    Collections.sort(list, new Comparator<Long>() {
      @Override
      public int compare(Long o1, Long o2) {
        return o1.compareTo(o2);
      }
    });
    System.out.println(list);
  }
}

解释:第一种方法是使用Collections工具类,Long类里面有Comparable接口的方法compareTo,第二种方法是使用Comparator中compare方法。下图是Long类的compareTo方法,已经给我们封装好了。

Java源码系列(1):Comparable和Comparator的区别

例子2:(对自定义对象数组的排序

1.使用Comparable:

public class Person implements Comparable<Person> {
  private String name;
  private int age;

  public Person(String name, int age) {
    this.name = name;
    this.age = age;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public int getAge() {
    return age;
  }

  public void setAge(int age) {
    this.age = age;
  }

  @Override
  public int compareTo(Person o) {
    return this.age - o.getAge();
  }
}
public class Test {
  public static void main(String[] args){
    List<Person> list=new ArrayList<>();
    list.add(new Person("易烊千玺",20));
    list.add(new Person("刘浩然",21));
    list.add(new Person("吴磊",18));
    Collections.sort(list);
    for(int i=0;i<list.size();i++){
      System.out.println(list.get(i).getName()+","+list.get(i).getAge());
    }
  }
}

结果:

Java源码系列(1):Comparable和Comparator的区别

2.使用Comparator

public class Person{
  private String name;
  private int age;

  public Person(String name, int age) {
    this.name = name;
    this.age = age;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public int getAge() {
    return age;
  }

  public void setAge(int age) {
    this.age = age;
  }
}
public class Test {
  public static void main(String[] args){
    List<Person> list=new ArrayList<>();
    list.add(new Person("易烊千玺",20));
    list.add(new Person("刘浩然",21));
    list.add(new Person("吴磊",18));
    Collections.sort(list, new Comparator<Person>() {
      @Override
      public int compare(Person o1, Person o2) {
        return o1.getAge()-o2.getAge();
      }
    });
    for(int i=0;i<list.size();i++){
      System.out.println(list.get(i).getName()+","+list.get(i).getAge());
    }
  }
}

结果:

Java源码系列(1):Comparable和Comparator的区别

综上所述,得出结论。

两者相同点:Comparable和Comparator都是用来实现集合元素的比较和排序的。

两者不同点:

Comparable是集合内部定义的方法,位于java.lang包下,是一个对象本身就已经支持比较需要实现的接口,比如String,Integer自己就实现了Comparable接口,那么他们就可以按照定义好的实现排序功能,也就是自然排序。

Comparator是集合外部实现的排序,位于java.util包下,是一个专用的比较器,不需要改变自身。