当前位置:网站首页>你了解如何比较两个对象吗
你了解如何比较两个对象吗
2022-06-26 18:01:00 【一只懐坏旭】
文章目录
一,关于对象值相等的比较
1, == VS equals
- p == q 表示的是 p 和 q 两个引用指向同一个对象
- p.equals(q) 表示 p 指向的对象 和 q 指向的对象是否是值语义相等的
2,代码示例
覆写equals前
class Card {
//扑克牌
public String rank; //点数
public String suit; //花色
public Card(String rank, String suit) {
this.rank = rank;
this.suit = suit;
}
}
public class TestCompare {
public static void main(String[] args) {
Card p = new Card("3","");
Card q = new Card("3","");
Card o = p;
System.out.println(o == p); //测试 == 比较身份
System.out.println(p == q);
System.out.println("===============================");
System.out.println(p.equals(o)); //测试比较内容
System.out.println(p.equals(q)); //没有重写的话,使用的是Object中的原始的equals方法,相当于依旧比较的是身份
}
}运行结果:
覆写equals后
class Card {
public String rank; //点数
public String suit; //花色
public Card(String rank, String suit) {
this.rank = rank;
this.suit = suit;
}
@Override
public boolean equals(Object obj) {
//按照值比较this和obj
// 1,自己与自己比较
if(this == obj){
return true;
}
//2,obj为null的情况
if(obj == null){
return false;
}
//3,obj类型不是当前card类型
if(! (obj instanceof Card) ){
return false;
}
//4,真正的比较内容
Card other = (Card)obj;
return this.rank.equals(other.rank) && this.suit.equals(other.suit);
}
}
public class TestCompare {
public static void main(String[] args) {
Card p = new Card("3","");
Card q = new Card("3","");
Card o = p;
System.out.println(o == p); //测试 == 比较身份
System.out.println(p == q);
System.out.println("===============================");
System.out.println(p.equals(o)); //测试比较内容
System.out.println(p.equals(q)); //重写后
}
}
注意: 一般覆写 equals 的套路就是上面演示的
- 如果指向同一个对象,返回 true
- 如果传入的为 null,返回 false
- 如果传入的对象类型不是 Card,返回 false
- 按照类的实现目标完成比较,例如这里只要花色和数值一样,就认为是相同的牌
- 注意下调用其他引用类型的比较也需要 equals,例如这里的 suit 的比较
二,关于对象值大于、等于、小于的比较-基于自然顺序
1,认识 Comparable
public interface Comparable<E> {
// 返回值:
// < 0: 表示 this 指向的对象小于 o 指向的对象
// == 0: 表示 this 指向的对象等于 o 指向的对象
// > 0: 表示 this 指向的对象等于 o 指向的对象
int compareTo(E o);
}2,代码示例
package java15_20200510;
class Card implements Comparable<Card>{
public String rank; //点数
public String suit; //花色
public Card(String rank, String suit) {
this.rank = rank;
this.suit = suit;
}
@Override
public int compareTo( Card o) {
//如果this比o小,返回一个小于0的整数
//如果this比o大,返回一个大于0的整数
//如果this == o,返回0
if(o == null){
//一般我们就认为this比o大,null比较小
return 1;
}
//点数取值2-10. JQKA
int rank1 = this.getValue();
int rank2 = o.getValue();
return rank1-rank2;
}
public int getValue(){
//通过这个方法把String类型变为整数点数
int value = 0;
if("j".equals(rank)){
value = 10;
} else if("Q".equals(rank)){
value = 11;
} else if("k".equals(rank)){
value = 12;
} else if("A".equals(rank)){
value = 14;
} else {
value = Integer.parseInt(rank);
}
return value;
}
}
public class TestCompare {
public static void main(String[] args) {
Card p = new Card("3","");
Card q = new Card("3","");
Card o = p;
System.out.println(p.compareTo(null));
System.out.println(p.compareTo(q));
}
}运行结果:
三, 关于对象值大于、等于、小于的比较-基于比较器
1, 认识 Comparator
public interface Comparator<T> {
// 返回值:
// < 0: 表示 o1 指向的对象小于 o2 指向的对象
// == 0: 表示 o1 指向的对象等于 o2 指向的对象
// > 0: 表示 o1 指向的对象等于 o2 指向的对象
int compare(T o1, T o2){
//Do
}
}2,代码示例
import java.util.Comparator;
class Card {
public String rank; //点数
public String suit; //花色
public Card(String rank, String suit) {
this.rank = rank;
this.suit = suit;
}
public int getValue(){
//通过这个方法把String类型变为整数点数
int value = 0;
if("j".equals(rank)){
value = 10;
} else if("Q".equals(rank)){
value = 11;
} else if("k".equals(rank)){
value = 12;
} else if("A".equals(rank)){
value = 14;
} else {
value = Integer.parseInt(rank);
}
return value;
}
}
class CarComparator implements Comparator<Card> {
@Override
public int compare(Card o1, Card o2) {
if(o1 == o2){
return 0;
}
if(o1 == null){
return -1;
}
if(o2 == null){
return 1;
}
int result1 = o1.getValue();
int result2 = o2.getValue();
return result1-result2;
}
}
public class TestCompare {
public static void main(String[] args) {
Card p = new Card("3","");
Card q = new Card("3","");
Card o = p;
CarComparator comparator = new CarComparator();
System.out.println(comparator.compare(p,q));
System.out.println(comparator.compare(p,null));
System.out.println(comparator.compare(null,q));
}
}运行结果:
四,比较

五,和 java 集合框架的配合
- 使用 contains 类似的方法,内部基本在调用元素的 equals 方法,所以要求元素覆写过 equals 方法
- 使用 HashMap,key 的比较内部会调用 equals 方法,所以要求元素覆写过 equals 方法
- 使用排序相关方法,内部需要进行比较,所以或者选择实现 Comparable 或者传入一个 Comparator
- 使用 TreeMap,key 需要进行大小比较,所以或者选择实现 Comparable 或者传入一个 Comparator
- 其他规则以此类推
六,注意事项
1,使用Comparable接口的时候,最好指定泛型参数.编译器自动的完成类型校验工作.如果不写泛型参数,默认的compareTo方法的参数类型就是Object类型.需要程序猿手动进行类型转换.
2,使用Comparable的时候,你必须让要比较的类实现Comparable接口. (需要修改这个类的代码)
3,使用Comparator的时候,你是重新创建一个新的类实现Comparator接口,不需要修改待比较类的代码
问题:为啥有了Comparable还需要有一个Comparato呢?
1,使用Comparator的时候必须要修改带比较类的代码,实际开发中不是所有的类都能修改源码(这个类是库或者其它组提供的)
2.Comparable只能定义一种比较规则,Comparator可以定义多种比较规则
边栏推荐
- [QNX] Command
- Analysis of deep security definition and encryption technology
- [buuctf.reverse] 126-130
- padding百分比操作
- [uniapp] the uniapp mobile terminal uses uni Troubleshooting of navigateback failure
- Get and set settings in 26class
- 力扣每日一题-第28天-566.重塑矩阵
- The difference between round and truncate in SQL (round or truncate)
- 有依赖的背包问题
- Using redis for user access data statistics hyperloglog and bitmap advanced data types
猜你喜欢

分页查询、JOIN关联查询优化

MySQL index

Leetcode HOT100 (22--- bracket generation)

RSA concept explanation and tool recommendation - LMN

二分查找法-1

Runtimeerror: CUDA error: out of memory own solution (it is estimated that it is not applicable to most people in special circumstances)

14《MySQL 教程》INSERT 插入数据

The difference between round and truncate in SQL (round or truncate)

贝叶斯网络详解

14 MySQL tutorial insert insert data
随机推荐
[buuctf.reverse] 126-130
Using redis for user access data statistics hyperloglog and bitmap advanced data types
9、智慧交通项目(2)
二分查找法-1
14 MySQL tutorial insert insert data
LeetCode——226. 翻轉二叉樹(BFS)
transforms.RandomCrop()的输入只能是PIL image 不能是tensor
【动态规划】剑指 Offer II 091. 粉刷房子
一起备战蓝桥杯与CCF-CSP之大模拟炉石传说
Detailed explanation of asymmetric cryptosystem
vutils. make_ A little experience of grid () in relation to black and white images
如何将应用加入到deviceidle 白名单?
#26class中get和set设置
The king of Internet of things protocol: mqtt
数据加密标准DES安全性
wechat_微信小程序中解决navigator进行页面跳转并传递参数问题
让torch.cuda.is_available()从false变成true的一点经验
贝叶斯网络详解
RSA concept explanation and tool recommendation - LMN
Static registration and dynamic registration of JNI