Comparable接口和Comparator接口
前言
Java中基本数据类型可以直接比较大小,但引用类型呢?同时引用对象中可能存在多个可比较的字段,那么我们该怎么比较呢?
Java中引用类型不能直接进行大小的比较,这种行为在编译器看来是危险的,所以会编译失败;
想要实现引用类型的比较,那么我们可以实现Comparable接口和Comparator接口
1 Comparable接口
Comparable接口是JDK提供的泛型比较接口类,源码实现大概如下:
//<T>中写比较的类
public interface Comparable<T> {//返回值// < 0,表示this指向的对象小于o指向的对象// > 0,表示this指向的对象大于o指向的对象// == 0,表示this指向的对象等于o指向的对象int compareTo(T o);
}
通常对于用户自定义类型,如果想要按照大小进行比较,那么我们需要在定义类的时候实现Comparable
接口,并重写compareTo
方法。
//存在一个Person类,根据年龄比较大小
public class Person implements Comparable<Person> {public String name;public int age;public Person(String name,int age) {this.name = name;this.age = age;}//重写compareTo方法int compareTo(Person o) {if(o == null) {return 1;}return this.age - o.age;}
}//Main.java
public class Main {public static void main(String[] args) {Person person1 = new Person("lisi",18);Person person2 = new Person("wangwu",35);//比较person1和person2的年龄大小System.out.println("person1 是否大于 person2 ?");System.out.println(person1.compareTo(person2) > 0);}
}
2 Comparator接口
基于比较器方式进行比较,Comparator定义如下:
//<T>中写比较的类
public interface Comparator<T> {//返回值// < 0,表示this指向的对象小于o指向的对象// > 0,表示this指向的对象大于o指向的对象// == 0,表示this指向的对象等于o指向的对象int compare(T o1,T o2);
}
我们知道Person类的比较不仅可以根据年龄还可以根据姓名来进行比较,但是当Comparable
接口中的compareTo
方法被重写后,我们就不能轻易修改,这时候该如何解决呢?
用户自定义比较器类,实现Comparator
接口,并重写其中的compare
方法。
//也就是说我们可以定义两个比较器类来实现接口Comparator接口
//AgeComparator.java实现年龄比较
public class AgeComparator implements Comparator<Person> {//根据年龄比较public int compare(Person o1,Person 02) {if(o1 == o1) {return 0;}if(o1 == null || 02 == null) {return -1;}return o1.age - o1.age;}} //NameComparator.java实现年龄比较
public class NameComparator implements Comparator<Person> {//根据年龄比较public int compare(Person o1,Person 02) {if(o1 == o1) {return 0;}if(o1 == null || 02 == null) {return -1;}return o1.name.compare(o2);}} //Main.java
public class Main {public static void main(String[] args) {Person person1 = new Person("lisi",18);Person person2 = new Person("wangwu",35);//根据自定义比较器类分别比较年龄和姓名System.out.println("根据姓名比较:");NameComparator nameComparator = new NameComparator();System.out.println("person1姓名 是否大于 person2姓名 ?");System.out.println(nameComparator.compare(person1,person2)> 0);System.out.println("根据年龄比较:");AgeComparator ageComparator = new AgeComparator();System.out.println("person1年龄 是否大于 person2年龄 ?");System.out.println(ageComparator.compare(person1,person2)> 0); }
}
Comparable接口和Comparator接口都可以用于对象的比较,Comparable
一般在当前类中使用,对当前类的侵入性比较强,Comparator
对当前类的侵入性较弱,可以脱离当前类使用,当需要实现一个比较器对象。
#对象的比较 对象的比较一般可以使用父类继承下来的equals()
方法(根据使用场景可重写)、实现Comparable
接口并重写其中的compareTo()
方法,构造比较器类实现Comparator
接口并重写compare()
方法。
重写方法 | 解释 |
---|---|
Object.equals(); | 所有类都继承于Object类 |
Comparable.compareTo(); | 自定义类手动实现接口,对当前类侵入性较强 |
Comparator.compare(); | 需要构造比较器类对象,对当前类侵入性较弱 |