equals
方法是 Java 中用于比较两个对象是否“相等”的方法。在 Java 中,每个类都继承自 java.lang.Object
类,而 equals
方法正是定义在 Object
类中的一个方法。默认情况下,Object
类的 equals
方法比较的是两个对象的内存地址(即引用是否指向同一块内存),而不是它们的内容。因此,如果你希望在自定义的类中实现基于内容的比较,你需要重写 equals
方法。
解疑:
-
为什么上面说
equals
方法比较的是两个对象是否“相等”,我写的 "abc".equals("abc") 比较的是内容值?
答案:在Java中,Object 类是所有类的超类(理解为它是所有类的父类或祖宗类),它提供了一个默认的 equals
方法实现。这个默认实现是比较两个对象的引用是否相同,即它们是否指向内存中的同一个对象。
(1)在Test类中输入Object:
Object
(2)左手按住Ctrl键,右手用鼠标点击Object 就可以查看Object类的底层源代码
(3)使用Ctrl+f键 输入equals 找到 equals实现方法
解读代码:
-
public boolean equals(Object obj)
:该方法接受一个类型为Object
的参数obj
,并返回一个布尔值。 -
return (this == obj);
:它使用==
运算符比较当前对象(this
)与传入的对象(obj
)的引用。
所以Object类的equals方法的底层源代码是用“==”来进行比较,当用于对象时,==
检查两个引用是否指向内存中的同一个对象,即它们是否是同一个对象实例。或者是说比较地址值(即对象的引用)
这种实现仅仅是比较两个对象的引用是否相同,而不是比较对象的内容(例如它们的属性或状态)。这就是为什么在大多数情况下,我们需要根据对象的实际内容重写 equals
方法。所以当你写的 "abc".equals("abc") 时实际上是调用了子类String 重写的equals方法。
String类重写了父类Object 的equals方法,内容如下:
public boolean equals(Object anObject) {if (this == anObject) {return true;}if (anObject instanceof String) {String anotherString = (String)anObject;int n = value.length;if (n == anotherString.value.length) {char v1[] = value;char v2[] = anotherString.value;int i = 0;while (n-- != 0) {if (v1[i] != v2[i])return false;i++;}return true;}}return false;}
分析如下:
同样的当你使用equals比较两个Integer类型的值时,Integer类也重写了equals方法,代码如下:
public boolean equals(Object obj) {if (obj instanceof Integer) {return value == ((Integer)obj).intValue();}return false;}
分析如下:
-
如果定义一个Person类,调用equals方法比较两个对象(如下代码),equals方法比较对象的内容(例如它们的属性或状态)还是比较是否是同一个对象呢?
Person person1=new Person("小明",18);Person person2=new Person("小明",18);System.out.println(person1.equals(person2));
答案:比较是否是同一个对象。Person类因为本身没有equals方法,但它是Object的子类(Object 类是所有类的超类,所以Person默认继承了Object类)Person调用是父类的equals方法,而父类的equals方法底层实现代码如下:
public boolean equals(Object obj) {return (this == obj);}
代码是用“==”来进行比较,当用于对象时,==
检查两个引用是否指向内存中的同一个对象,显然person1和person2是两个不同的对象(变量名不同)。如果我们想要有一个 Person
类,并且你想要比较两个 Person
对象是否具有相同的名字和年龄,那么你需要重写 equals
方法来比较这些属性,而不是仅仅比较它们的引用。
重写equals代码思路:
1.从特殊到一般:先把最特殊的情况写出来(即两个对象是同一个对象:对象的引用相同都指向同一个对象)
2.判断是否是同一类(即判断是不是Person类)
obj instanceof Person
3.判断属性值是否相等
以下是重写equals的详细代码:
package Test;public class Person {private String name;private int age;public Person(String name,int age){this.name=name;this.age=age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
// 思路:从特殊到一般!!!
// 如果是同一个对象直接返回true 同一个对象相当于对象引用指向同一对象
// 判断同类类型的对象的属性是否相同,先判断同一类型,再判断属性值
// 重写equals方法:public boolean equals(Object obj) {if (this == obj){return true;} else if (obj instanceof Person) {Person person=(Person) obj;return person.name.equals(name) && person.age==age;}return false;}public static void main(String[] args) {Person person1=new Person("小明",18);Person person2=new Person("小明",18);System.out.println(person1.equals(person2));}
}