
提到这个 Object 类 中的 equals() 方法,很多人对其都有一个错误的认知,并且这个==和equals() 方法的区别一直是面试中的高频考点,今天阿牛就带你看看并且重写equals方法!
对于 == 运算符的使用,我不再写案例,相比大家对他都是很清楚的!
== 运算符对于引用数据类型变量,比的是地址值,但是我们就想比较两个引用类型内容是否相同该怎么办呢!这时equals()方法就起作用了!
我们看下面例子:
package 重写equals;
public class Demo {
public static void main(String[] args) {
String str1 = new String("aniu");
String str2 = new String("aniu");
String str3 = "tom";
String str4 = "tom";
System.out.println(str3==str4);// true,str3和str4字符串在常量池中,不是new的对象,所以可以用==直接比较
System.out.println(str1==str2);//false,str1和str2是引用类型,==比的是地址,所以要用equals比较
System.out.println(str1.equals(str2)); //true
}
}

看了这个例子会给你一个错觉,认为equals()比较的是引用类型的值!
那么你再看这个例子:
package 重写equals;
public class Demo {
public static void main(String[] args) {
Person p1 = new Person("aniu",21);
Person p2 = new Person("aniu",21);
System.out.println(p1.equals(p2)); //false
}
}
class Person{
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public void work(){
System.out.println("走哇!");
}
}

不是说equals()比的是内容吗,p1和p2对象的属性值一样,为什么会输出false呢?
要解决这个问题,我们要看equals()的源码:
将鼠标放到上述代码的equals()方法上,ctrl+b查看源码
public boolean equals(Object obj) {
return (this == obj);
}
我们可以看到equals()内部也是==运算符,对于引用类型,这不比较的也是地址嘛!当然会输出false,那第一个例子的String类型中的equals()又是怎么回事,咋就输出true呢!我们同样看String中的equals()源码:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
return (anObject instanceof String aString)
&& (!COMPACT_STRINGS || this.coder == aString.coder)
&& StringLatin1.equals(value, aString.value);
}
public static boolean equals(byte[] value, byte[] other) {
if (value.length == other.length) {
for (int i = 0; i < value.length; i++) {
if (value[i] != other[i]) {
return false;
}
}
return true;
}
return false;
}
很明显,String类将Object类中的equals()方法重写了!
因此!我们要比较两个类是否相同,也需要重写Object类中的equals()方法!
总结:
equals ()方法的使用:
public boolean equals (Object obj ){
return ( this == obj );
}
说明: Object 类中定义的 equals ()和 == 的作用是相同的,比较两个对象的地址值是否相同。
像 String 、 Date 、 File 、包装类等都重写了 Object 类中的 equals ()方法。重写以后,比较的不是两个引用的地址是否相同,而是比较两个对象的"实体内容"是否相同。
通常情况下,我们自定义的类如果使用 equals ()的话,也通常是比较两个对象的"实体内容"是否相同。那么,我们就需要对 Object 类中的 equals ()进行重写!
我们参考String类中重写的equals()方法以及我们自己的理解,手动重写一下自定义类中的equals()方法。
重写的原则,比较两个对象的实体内容是否相同!
package 重写equals;
public class Demo {
public static void main(String[] args) {
Person p1 = new Person("aniu",21);
Person p2 = new Person("aniu",21);
System.out.println(p1.equals(p2));
}
}
class Person{
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public void work(){
System.out.println("走哇!");
}
//手动重写equals()方法
@Override
public boolean equals(Object obj) { // 参数将其进行了上转型,使其可以接受任何对象
//如果两个对象的地址值相同
if (this == obj){
return true;
}
if (obj instanceof Person){
Person p = (Person) obj; //下转型
return this.age == p.age && this.name == p.name; // 比较两个对象的属性值是否相同
}
return false;
}
}

可以看到此时为true了!
在开发中我们往往用idea帮助我们自动重写equals()方法,并且自动重写的equals()方法也更加规范,接下来看看操作步骤吧!
首先,在idea中用快捷键Alt+Insert:

点击之后

设置如上图这样后点击Next

将两个属性全部勾选后继续Next

hashCode()方法也一样!Next

不勾选,Finish,然后我们的equals()方法就自动重写好了!
package 重写equals;
public class Demo {
public static void main(String[] args) {
Person p1 = new Person("aniu",21);
Person p2 = new Person("aniu",21);
System.out.println(p1.equals(p2));
}
}
class Person{
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public void work(){
System.out.println("走哇!");
}
// 自动重写equals()
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Person)) return false;
Person person = (Person) o;
if (age != person.age) return false;
return name != null ? name.equals(person.name) : person.name == null;
}
}

运行是true,没有问题!
注意 name.equals() 调的是String里面重写的equals()方法!
相信通过上面的内容,现在你可以正确的说出 == 和 equals 的区别了
如果你觉得博主写的还不错的话,可以关注一下当前专栏,博主会更完这个系列的哦!也欢迎订阅博主的其他好的专栏。
🏰系列专栏
👉软磨 css
👉硬泡 javascript
👉flask框架快速入门