Java中对象⽐较的三种⽅式
⼀. 针对对象值是否相等的⽐较
== 和 equals 的区别
当我们提到⽐较值的时候,⼤多数⼈都会想到 == ,因为在⼀般情况下,⼈们对于⽐较的概念中,数字⽐较的应⽤场景出现频率是最多的.
⾸先我们创建⼀个类,之后新建这个类的对象来进⾏⽐较验证.
class Student {
public String name;
public int score;
public Student(String name,int score){
this.name = name;
this.score = score;
}
}
==
我们通常都⽤ == 来⽐较数字的⼤⼩,那如果⽤他来⽐较对象会是什么情况,看下⾯⼀个代码.
Student student1 =new Student("⼩明",95);
Student student2 =new Student("⼩明",95);
if(student1 == student2){
System.out.printf("相等");
}else{
System.out.println("不相等");
}
这段代码中我们创建了包含实例相同的两个对象,都是⼩明,95分.在运⾏之前我们也许会想它是相同的,但实则不然,结果为不相等.下⾯我们再提供⼀段相似的代码.
Student student1 =new Student("⼩明",95);
Student student2 = student1;
if(student1 == student2){
System.out.println("相等");
}else{
System.out.println("不相等");
}
这段代码的结果为相等.为什么?
第⼀段代码中我们 new 了两个对象,但其实 == 在⽐较对象时,⽐较的是对象的⾝份(地址),每新建⼀个对象就会开辟⼀块内存, student1引⽤⼀个对象,⽽ student2 也引⽤⼀个内容⼀样但是地址不同的对象.
equals
上⾯提到了 == 的应⽤场景,但是我们所需要的是⽐较两个不同对象的内容是否相等,这⾥则需要对类中的 equals ⽅法进⾏覆写,来针对对象的特定实例域来进⾏⽐较,判断他们是否相等.
public class Student {
public String name;
public int score;
public Student(String name,int score){
this.name = name;
this.score = score;
}
@Override
equals不等于public boolean equals(Object obj){
if(this== obj){
return true;
}
if(obj == null){
return false;
}
Class()!= Class()){
return false;
}
Student other =(Student)obj;
return this.score == other.score
&&this.name.equals(other.name);
}
}
equals 必须要⽐较的⼏点:
1. 如果引⽤了同⼀个对象,返回 true
2. 如果传⼊参数为 null,由于调⽤者不可能为 null,返回 false
3. 如果这两个对象的类型不⼀样(getClass()可以获得对象的类型),返回false
4. 最后要完成两个对象实例域的⽐较,这⾥⽐较成绩和姓名是否相同,(因为姓名是 String 类型,所以需要使⽤String类型的 equals 来进⾏
⽐较,这⾥的equals 和我们覆写的equals ⽅法有所区别),返回 true,否则返回 false.
下⾯我们创建两个实例相同的对象和⼀个不同的对象来进⾏⽐较.
Student student1 =new Student("⼩明",98);
Student student2 =new Student("⼩明",98);
Student student3 =new Student("⼩红",95);
System.out.println(student1.equals(student2));
System.out.println(student1.equals(student3));
输出结果为
true
false
⼆. 针对对象值⼤于⼩于和等于的⽐较(⾃然顺序)
在⽐较了是否相等以后,我们也需要对学⽣的成绩来进⾏排名,但是每次新建的⼀个对象都是由姓名和得分这两个实例域构成的,所以我们需要在学⽣这个类中实现 Comparable 接⼝,来覆写该接⼝中的 compareTo ⽅法.这⾥我们要让学⽣类实现这个接⼝,并且覆写接⼝中的⽅法.
class Student implements Comparable<Student>{
public String name;
public int score;
public Student(String name,int score){
this.name = name;
this.score = score;
}
@Override
public int compareTo(Student o){
if(o == null){
//这⾥设定任何对象都是⼤于null的
return1;
}
return this.score - o.score;
}
}
观察这个覆写的 compareTo ⽅法,这⾥规定如果传进来的对象参数是 null , 则说明调⽤该⽅法的对象⼤于对象o.两个对象的分数实例域进⾏⽐较,如果调⽤⽅法的对象成绩⼤于被⽐较对象o,则返回正数,反之就返回⼀个负数,相等就返回0.
下⾯我们来对这个覆写⽅法制定的规则进⾏验证.
Student student1 =new Student("⼩明",98);
Student student2 =new Student("⼩红",95);
if(student1pareTo(student2)>0){
System.out.println("student1的分数⽐student2的分数⾼");
}else if(student1pareTo(student2)<0){
System.out.println("student2的分数⽐student1的分数⾼");
}else{
System.out.println("student1的分数与student2的分数相等");
}
这段代码的输出结果为 student1的分数⽐student2的分数⾼.使⽤这样⼀个覆写 Comparable 接⼝的 compareTo ⽅法,能够很⽅便的让我们针对对象特定实例域来⽐较对象的⼤⼩.
三. 针对对象值⼤于⼩于和等于的⽐较(⽐较器)
刚才我们覆写的⽅法⽐较⽅式为⼀个⼀个对象引⽤调⽤⽅法,与⽅法传进来的参数进⾏⽐较.但如果我们想要使⽤⽅法来对两个传⼊的对象参数进⾏⽐较呢?
这时我们可以再创建⼀个类来做⽐较器,同时这个类要实现 Comparator 对象,再在这个⽐较器类中覆写 compare ⽅法,这个⽅法的参数是两个,再将内部的⼤⼩规则进⾏设定,就可以实现我们想要的效果.
public class ScoreComparator implements Comparator<Student>{
@Override
public int compare(Student o1, Student o2){
if(o1 == o2){
return0;
}
if(o1 == null){
return-1;
}
if(o2 == null){
return1;
}
return o1.score - o2.score;
}
}
这个覆写⽅法中传⼊了两个引⽤参数,相等就返回0, o1 的分数⾼就返回正数,反之返回负数.
下⾯来对这个覆写⽅法进⾏测试,我们还是使⽤刚才创建出来的两个学⽣对象为例来进⾏⽐较.
Student student1 =new Student("⼩明",98);
Student student2 =new Student("⼩红",95);
//创建⽐较器对象⽤来调⽤compare⽅法
ScoreComparator scoreComparator =new ScoreComparator();
if(scoreComparatorpare(student1,student2)>0){
System.out.println("student1的分数⽐student2的分数⾼");
}else if(scoreComparatorpare(student1,student2)<0){
System.out.println("student2的分数⽐student1的分数⾼");
}else{
System.out.println("student1的分数与student2的分数相等");
}
这段代码运⾏的结果和刚才⼀样,都是student1的分数⽐student2的分数⾼,符合我们制定的⽐较规则.由于我们需要调⽤这个⽅法,所以要先创建⼀个⽐较器的类,这个类中覆写的 compare ⽅法也是针对 Student 学⽣类的分数来进⾏⽐较的,在使⽤的时候必须要创建⼀个⽐较器对象才能调⽤ compare ⽅法.
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论