Java中基本类型间的元素比较,可以直接通过">"、"<"、"=="等符号判断大小,也可使用compareTo比较大小或者equals判断是否相等,作为引用类型的String类不可以使用">"、"<"比较大小,但可以使用"=="判断相等,实际上,Java中的"=="就相当于调用了equals方法,八大基础类型的包装类中都包含了equals方法, String类作为引用类型,也包含了equals方法,String虽然不能直接使用">"、"<"比较,但可以通过compareTo方法比较。
目录
对象比较的三种方法
重写equals方法比较
实现Comparable接口比较
实现Comparator接口比较
对象比较的三种方法
基本类型的比较可以通过以上方式实现,那么对象的比较呢?
例如我创建一个学生类:
public class Students {
public int age;
public String name;
public Students(int age, String name) {
this.age = age;
this.name = name;
}
public static void main(String[] args) {
Students student1 = new Students(15, "zhangsan");
Students student2 = new Students(15, "zhangsan");
student1.equals(student2);
}
}
重写equals方法比较
初始化两个完全一样的对象,可以使用euqals方法,但这里可以使用equals方法只是因为任何类都是Object类的子类,equals方法不能识别到确定的类型,就会调用object的equals方法,也就是:
//object类的equals方法源码
public boolean equals(Object obj) {
return (this == obj);
}
并不会比较对象中的内容,因此得到的结果只能是false。
如果非要通过equals方法来比较,必须重写equals方法:
接着一路next最后create,即可生成以下代码:
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Students students = (Students) o;
return age == students.age && Objects.equals(name, students.name);
}
@Override
public int hashCode() {
return Objects.hash(age, name);
}
这时便可以进行对象的比较了。
实现Comparable接口比较
equals方法只能比较是否相等,要比较出大小,还必须依赖于compareTo方法,要使用compareTo方法,需要实现Comparble泛型接口,然后重写compareTo方法即可,例如通过年龄比较:
@Override
public int compareTo(Students o) {
return this.age - o.age;
}
实现Comparator接口比较
当然,这种写法只能限定一种比较规则,当我们需要比较其他的内容时又不方便,为了使比较方式更加灵活,可以创建一个比较器类实现Comparator接口,再通过调用比较器的compare方法实现比较。
例如创建一个基于年龄比较的比较器:
class AgeComparator implements Comparator<Students> {
@Override
public int compare(Students o1, Students o2) {
return o1.compareTo(o2);
}
}
比较时只需实例化比较器对象并调用compare方法即可。
某些对象的创建需要传入比较器,比如说建立大根堆,PriorityQueue默认是建立小根堆,要建立大根堆,需要传入比较器,其具体写法可以有三种:
写法一:新建一个比较器类如上所示,实例化对象后作为参数传入。
AgeComparator ageComparator = new AgeComparator();
PriorityQueue<Integer> priorityQueue = new PriorityQueue<>(ageComparator);
写法二:直接在括号中新建比较器,省去实例化的过程:
PriorityQueue<Integer> priorityQueue = new PriorityQueue<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2.compareTo(o1);
}
});
写法三:写成lambda式(实际是写法二的简化):
PriorityQueue<Integer> priorityQueue = new PriorityQueue<>((o1, o2) -> { return o2.compareTo(o1);} );
三种比较方式各有特点:
重写equals方法方便快捷,但仅能判断相等,不能比较大小。
使用Comparable.compareTo方法需要实现接口,且比较方式单一。
使用Comparator.compare方法则需要创建一个比较器对象,再通过比较器进行比较。