前言
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(); | 需要构造比较器类对象,对当前类侵入性较弱 |