java_equals()和null

package equals;
import java.util.List;
import java.util.Objects;
/*自反性/对称性是针对某种"关系"而言,比如像这样的说法:关系R具有自反性*/
/*如何正确编写(重写)equals()方法?equals()方法要求我们必须满足以下条件:
自反性(Reflexive):对于非null的x来说,x.equals(x)必须返回true;
对称性(Symmetric):对于非null的x和y来说,如果x.equals(y)为true,则y.equals(x)也必须为true;
传递性(Transitive):对于非null的x、y和z来说,如果x.equals(y)为true,y.equals(z)也为true,那么x.equals(z)也必须为true;
一致性(Consistent):对于非null的x和y来说,只要x和y状态不变,则x.equals(y)总是一致地返回true或者false;
对null的比较:即x.equals(null)永远返回false。*/
public class equal3 {
/*判断相等关系时,有两类:
* 对于引用字段比较,我们使用equals(),(当然可以类似的达到像cpp的重载运算符的效果,只是cpp直接用符号,而java是用一个标识符(其实cpp也可以只用标识符,用符号只是形象些,但不必须)
* 对于基本类型字段的比较,我们使用== 来做相等性判断*/
/*java.lang.Object @Contract(value = "null -> false", pure = true)
public boolean equals(Object obj)
可见,equals()是继承自根类Object的方法,就是说任何类都有equals方法;但是我们往往需要自己重写这个重要方法:*/
public static void main(String[] args) {
List<Person1> list = List.of(
new Person1("Xiao", "Ming", 18),
new Person1("Xiao", "Hong", 25),
new Person1("Bob", "Smith", 20)
);
boolean exist = list.contains(new Person1("Bob", "Smith", 20));
System.out.println(exist ? "测试成功!" : "测试失败!");
}
}
class Person1 {
String firstName;
String lastName;
int age;
/*constructor*/
public Person1(String firstName, String lastName, int age) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
/*override equals*/
public boolean equals(Object o) {
/*注意equals()的参数类型一定要是Object(引用类型的根类),也就是说不能用equals来比较基础类型;
对于基础类型的比较,equals这是多余的,也是不必要的,用"=="足矣;
再次强调下,String类不是基础类型,是正儿八经的对象,尽量用equals来做相等性判断*/
if (o instanceof Person1) {
/*如果传入的对象是Person1,那么放心的将对象o强制转为Person1,赋值给Person1*/
Person1 p = (Person1) o;
/*object类中的equals已经处理好在引用类型String/Integer/基础类型..的(自反性/对称性/..等要求)
* 即,要简化引用类型的比较,我们使用Objects.equals()静态方法:
* java.util.Objects @Contract(value = "null, !null -> false; !null, null -> false", pure = true)
public static boolean equals(@Nullable Object a,Object b);
* 注意静态方法的调用方式(类名.静态方法名(必要的参数,(一般比普通方法要多传入一个参数))*/
return Objects.equals(this.firstName, p.firstName) && Objects.equals(this.lastName, p.lastName) && this.age == p.age;
}
return false;
}
}
/*equals()遇到null时:
public class Person {
public String name;
public int age;
}
public boolean equals(Object o) {
if (o instanceof Person) {
Person p = (Person) o;
return this.name.equals(p.name) && this.age == p.age;
}
return false;
}
如果this.name为null,那么equals()方法会报错,因为null为空引用,是一个特殊值,不是某种对象(实例),更加不会提供/支持任何方法(通过null调用方法是荒谬的),
应该先让this.name和null先做判断;
当然,null可以作为参数传入个其他(对象)的方法;
因此,需要继续改写如下:
public boolean equals(Object o) {
if (o instanceof Person) {
Person p = (Person) o;
boolean nameEquals = false;
//null和null的等与不等:
//对象A==null同时对象B==null,那么null作为桥梁,间接表示A和B相等(在equals()的实现中体现为返回true)
if (this.name == null && p.name == null) {
nameEquals = true;
}
if (this.name != null) {
nameEquals = this.name.equals(p.name);
}
return nameEquals && this.age == p.age;//出口1
}
return false;//出口2;
}*/
posted @   xuchaoxin1375  阅读(54)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
历史上的今天:
2023-08-18 计算字符串中子串出现的次数 输入 输入以空格相隔的两个字符串(字符数不大于20个),敲回车 输出 统计第一个字符串中 第二个字符串 出现的次数 样例输入 Goodoo o 样例输出 4
2023-08-18 android开发入门+进阶学习建议
2023-08-18 java_利用hanlp对文件“三国演义(罗贯中).txt”进行分词,去掉标点符号和停用词, 最后统计词频,排序输出到文件“三国演义词频.txt“
2023-08-18 c/python:_分解质因数:
点击右上角即可分享
微信分享提示