java对象的比较
一、基本类型的比较
在Java中,基本类型的对象可以直接比较大小。
(<,>,>=,<=,==,!=)
==运算符比较:
基本数据类型,比较值是否相同
引用类型,比较引用变量的首地址是否相同
二、equals
equals 有两种判断方式,但是都是建立在引用类型上的比较
1.当我们的子类没有重写equals 时,我们调用的时Object 的equals方法,只能判断两个引用类型的地址是否相同;
2.当我们的子类重写equals 时,可以判断的是内容是否相等,这里判断的规则我们自己写。(我自己这么理解的)
public class Card {
public int rank; // 数值
public String suit; // 花色
public Card(int rank, String suit) {
this.rank = rank;
this.suit = suit;
}
//重写相当于自己定义比较规则
@Override
public boolean equals(Object o) {
// 自己和自己比较,如果相等返回true
if (this == o) {
return true;
}
//o如果是null对象,或者o不是Card的子类
if (o == null || !(o instanceof Card)) {
return false;
}
//注意基本类型可以直接比较,但引用类型最好调用其equal方法
Card c = (Card) o;
return rank == c.rank
&& suit.equals(c.suit); //这里是直接比较数值的大小
}
}
**注意: 一般覆写 equals 的套路就是上面演示的
- 如果指向同一个对象,返回 true
- 如果传入的为 null,返回 false
- 如果传入的对象类型不是 Card,返回 false
- 按照类的实现目标完成比较,例如这里只要花色和数值一样,就认为是相同的牌
- 注意下调用其他引用类型的比较也需要 equals,例如这里的 suit 的比较覆写基类equal的方式虽然可以比较,但缺陷是:equal只能按照相等进行比较,不能按照大于、小于的方式进行比较。**
equalsgnoreCase 比较的是内容并且忽略大小写。
三、Comparble比较器
Comparable接口
Comparble是JDK提供的泛型的比较接口类,源码实现具体如下:
public interface Comparable
{ public int compareTo(T o);
}
该接口只存在一个public int compareTo(T o);
方法,该方法表示所在的对象和o对象进行比较,返回值分三种:
1: 表示当前对象大于o对象
0: 表示当前对象等于o对象
-1: 表示当前对象小于o对象
对用用户自定义类型,如果要想按照大小与方式进行比较时:在定义类时,实现Comparble接口即可,然后在类中重写compareTo方法
举个栗子:
需求: 在优先级队列中存储对象学生,每个学生有id,name,age三个属性,并且使优先级队列每次按照学生的id从小到大取出。
代码示例:
Student类: 当前类实现了Comparable接口
,即当前类提供了默认的比较方法。
实现接口,创建自定义类
public class Student implements Comparable{
private int id;
private String name;
private int age;
public Student(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
public int getId() {
return id;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
//重写compareTo方法
@Override
public int compareTo(Object o) {
Student o1 = (Student)o;
return this.id - o1.id;
}
}
Comparator比较器
如果使优先级队列按照学生id从大到小取出呢?我们很快就会想到修改Student类的compareTo方法,使return o1.id - this.id;,这样当然可以实现我们的新需求。但是有很多时候类的compareTo方法是不能修改的,比如JDK给我们提供的源代码,在不修改compareTo方法的前提下实现需求,只能用Comparator比较器了。
Comparator接口
public interface Comparator
{ int compare(T o1, T o2);
}
该接口中提供了int compare(T o1, T o2)方法,该方法需要参数是两个待比较的对象
返回结果是int类型:
1: 表示o1对象大于o2对象
0: 表示o1对象等于o2对象
-1: 表名o1对象小于o2对象
覆写Comparator中的compare方法
import java.util.Comparator;
class Card {
public int rank; // 数值
public String suit; // 花色
public Card(int rank, String suit) {
this.rank = rank;
this.suit = suit;
}
}
class CardComparator implements Comparator<Card> {
// 根据数值比较,不管花色
// 这里我们认为 null 是最小的
@Override
public int compare(Card o1, Card o2) {
if (o1 == o2) {
return 0;
} if
(o1 == null) {
return -1;
}
if (o2 == null) {
return 1;
}
return o1.rank - o2.rank;
}
public static void main(String[] args){
Card p = new Card(1, "♠");
Card q = new Card(2, "♠");
Card o = new Card(1, "♠");
// 定义比较器对象
CardComparator cmptor = new CardComparator();
// 使用比较器对象进行比较
System.out.println(cmptor.compare(p, o)); // == 0,表示牌相等
System.out.println(cmptor.compare(p, q)); // < 0,表示 p 比较小
System.out.println(cmptor.compare(q, p)); // > 0,表示 q 比较大
}
}
注意:Comparator是java.util 包中的泛型接口类,使用时必须导入对应的包。
三种方式的比较
覆写的方法 | 说明 |
Object.equals | 因为所有类都是继承自 Object 的,所以直接覆写即可,不过只能比较相等与 否 |
Comparable.compareTo | 需要手动实现接口,侵入性比较强,但一旦实现,每次用该类都有顺序,属于 内部顺序 |
Comparator.compare | 需要实现一个比较器对象,对待比较类的侵入性弱,但对算法代码实现侵入性 强 |
还没有评论,来说两句吧...