Comparable和Comparator区别
1、Comparable是内部比较器,仅针对某个类进行比较,和具体类绑定,而Comparator是外部比较器,适用于多种类,只需要建立这些类的比较器即可。
2、另外,Comparator实际上是一种策略模式,比如TreeMap / TreeSet中持有Comparator接口的引用Comparator comparator
,通过TreeMap(排序类)的构造参数传入不同的Comparator实现类,就制定了TreeMap中key的不同比较规则。两个排序同时存在时采用 Comparator(定制排序)的规则进行比较。
例子:
public interface Comparable<T> {
public int compareTo(T o);
}
一个类要想能够比较,需要实现Comparable接口,重写compareTo方法
public interface Comparator<T> {
int compare(T o1, T o2);
boolean equals(Object obj);
// 其他已经实现的方法
}
// 采用Comparable实现比较,必须向原有类中增加重写的compareTo方法,会改变类的内容。
public class Person implements Comparable<Person> {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public int compareTo(Person p) {
return this.age - p.age;
}
@Override
public String toString() {
return name + ":" + age;
}
}
public class Test {
public static void main(String[] args) {
Person p1 = new Person("zz", 2);
Person p2 = new Person("z", 1);
Person p3 = new Person("zzz", 3);
List<Person> persons = new ArrayList<>();
persons.add(p1);
persons.add(p2);
persons.add(p3);
Collections.sort(persons);
System.out.println(persons);
}
}
// 输出
[z:1, zz:2, zzz:3]
// 如果要求不能改变类的内容,那么只能使用Comparator比较器。比如我们修饰Person类为final的
// 使用Comparator只需要重写compare方法,为什么没重写Comparator中的equals方法?因为任何类都继承自Object类,实现Comparator接口的类也不例外,而Object类中已经实现了equals方法,所以我们可以不用重写equals方法
public final class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return name + ":" + age;
}
}
public class Test {
public static void main(String[] args) {
Person p1 = new Person("zz", 2);
Person p2 = new Perosn("z", 1);
Person p3 = new Person("zzz", 3);
List<Person> persons = new ArrayList<>();
persons.add(p1);
persons.add(p2);
persons.add(p3);
Collections.sort(persons, new Comparator<Person>() {
@Override
public int compare(Person p1, Perosn p2) {
return p1.age - p2.age;
}
});
System.out.println(persons);
}
}
// 输出
[z:1, zz:2, zzz:3]