Comparable接口
Comparable接口是java.lang包下的一个接口,它用来进行比较,如果需要按照某种规则对对象进行比较,可以实现这个接口。Comparable接口是一个内比较器,因为它的比较逻辑是写在类中被重写的ComparableTo方法内的。
接口中的CompareTo方法有3种情况,如果比较者和被比较者相等,返回0,如果比较者大于被比较者,返回正数,如果比较者小于被比较者,返回负数。
public interface Comparable<T> {
public int compareTo(T o);
}
怎么使用Comparable接口
进行比较的对象需要实现Comparable接口,并在类中重写ComparableTo方法。
public class Person implements Comparable<Person>{
private String name;
private int 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 Person() {
super();
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
@Override
public int compareTo(Person o) {
if (this.age > o.getAge()) {
return 1;
}
if (this.age < o.getAge()) {
return -1;
}
return 0;
}
}
如果一个实现了Comparable接口,那么调用Collections.sort方法进行排序底层使用的就是Comparable接口的ComparableTo方法。另外实现了Comparable接口的类是可以和自身进行比较的。
public class Main {
public static void main(String[] args) {
ArrayList<Person> arrayList = new ArrayList<>();
arrayList.add(new Person("张三", 17));
arrayList.add(new Person("李四", 20));
arrayList.add(new Person("赵六", 19));
arrayList.add(new Person("王五", 23));
for(Person person : arrayList) {
System.out.println(person.getName() + ":" + person.getAge());
}
System.out.println("----------------------------------------------------");
//调用集合工具类进行排序,底层调用的是CompareTo方法
Collections.sort(arrayList);
for(Person person : arrayList) {
System.out.println(person.getName() + ":" + person.getAge());
}
System.out.println("----------------------------------");
//直接对两个对象进行比较
System.out.println(new Person("张三", 17).compareTo(new Person("李四", 20)));
}
}
Comparator接口
Comparator接口是java.util包下的一个接口,Comparator接口内有一个compare方法,这个方法内部是比较的逻辑,比较的返回值和Comparable接口中的ComparableTo方法是一样,这个接口也是用来实现比较的,但是这个接口相当于外比较器,因为比较的的逻辑是写在外部的。
public class Person {
private String name;
private int 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 Person() {
super();
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
当对象不支持自比较或者自比较不能满足需求时,可以使用Comparator接口。
public class Main {
public static void main(String[] args) {
ArrayList<Person> arrayList = new ArrayList<>();
arrayList.add(new Person("张三", 17));
arrayList.add(new Person("李四", 20));
arrayList.add(new Person("赵六", 19));
arrayList.add(new Person("王五", 23));
for(Person person : arrayList) {
System.out.println(person.getName() + ":" + person.getAge());
}
System.out.println("----------------------------------------------------");
Collections.sort(arrayList, new Comparator<Person>() {
//比较的逻辑,这里是根据年龄来比较
@Override
public int compare(Person o1, Person o2) {
return o1.getAge() - o2.getAge();
}
});
for(Person person : arrayList) {
System.out.println(person.getName() + ":" + person.getAge());
}
}
}
结果
区别
使用Comparable接口进行比较耦合度比较高,因为比较的方法ComparableTo是写在需要比较的类中的,如果比较的策略改变需要对类进行改变,而Comparator则避免了这个缺点,Comparator使用的是策略模式。
在上面的代码中实际上是用Comparable接口和Comparator接口分别对Person类实现了比较,如果一个类已经存在但是没有实现比较现在想要进行比较,可以使用Comparator接口,这样不用改变现有的类。