💡 一则也许对你有用的小广告 🏆
欢迎飞飞程序员 ,你将获得:专属的实战项目(已更新的所有会员标识的项目都能学习) / 1v1 提问 / Java 学习路线 / PHP 学习路线 / 学习打卡 / 社群讨论
截止目前, 飞飞 正在疯狂爆肝实战项目,后续还会上新更多项目,目标是将所学知识开发成项目并且分享给大家,如知识付费系统, Ai系统, CMS系统,在线商城系统,等等 ,欢迎点击围观
在 Java 中,equals() 方法用于比较两个对象是否“逻辑相等”,而不是比较引用地址(== 比较的是引用地址)。它是 Object 类的一个方法,可以被所有类继承和重写。以下是 equals() 的详细用法和注意事项:
1. equals() 方法的基本用法
1.1 Object 类的默认 equals() 方法
默认情况下,Object 类的 equals() 方法的行为与 == 相同,即比较两个对象的内存地址:
public boolean equals(Object obj) {
return (this == obj);
}
示例:
String str1 = new String("hello");
String str2 = new String("hello");
System.out.println(str1 == str2); // false(比较地址)
System.out.println(str1.equals(str2)); // true(比较内容)
1.2 重写 equals() 方法
为了让 equals() 比较对象的内容(而非地址),我们需要在自定义类中重写它。例如:
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true; // 如果是同一个对象,直接返回 true
if (obj == null || getClass() != obj.getClass()) return false; // 类型不同返回 false
Person person = (Person) obj; // 强制类型转换
return age == person.age && name.equals(person.name); // 比较属性
}
}
测试:
Person p1 = new Person("Alice", 25);
Person p2 = new Person("Alice", 25);
System.out.println(p1.equals(p2)); // true(比较 name 和 age)
2. equals() 方法的规范
重写 equals() 时,必须遵循以下规则(Java 规范):
- 自反性(Reflexive)
x.equals(x) 必须返回 true。
- 对称性(Symmetric)
如果 x.equals(y) 返回 true,那么 y.equals(x) 也必须返回 true。
- 传递性(Transitive)
如果 x.equals(y) 和 y.equals(z) 都返回 true,那么 x.equals(z) 也必须返回 true。
- 一致性(Consistent)
多次调用 x.equals(y) 应该始终返回相同的结果(除非对象被修改)。
- 非空性(Non-null)
x.equals(null) 必须返回 false。
3. 如何正确重写 equals()
3.1 标准重写模板
@Override
public boolean equals(Object obj) {
if (this == obj) return true; // 1. 检查是否同一个对象
if (obj == null || getClass() != obj.getClass()) return false; // 2. 检查 null 和类型
MyClass other = (MyClass) obj; // 3. 强制类型转换
// 4. 比较所有关键字段
return field1.equals(other.field1)
&& field2 == other.field2
&& Objects.equals(field3, other.field3); // 使用 Objects.equals 避免 NPE
}
3.2 使用 Objects.equals() 避免 NullPointerException
如果字段可能为 null,可以用 Objects.equals() 替代 field.equals():
import java.util.Objects;
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
MyClass other = (MyClass) obj;
return Objects.equals(this.name, other.name) // 安全比较
&& this.age == other.age;
}
4. equals() 与 hashCode() 的关系
- 规则:如果两个对象
equals() 返回 true,它们的 hashCode() 必须相同。
- 原因:
HashMap、HashSet 等依赖 hashCode() 进行快速查找,如果违反此规则,会导致哈希表行为异常。
示例:
@Override
public int hashCode() {
return Objects.hash(name, age); // 自动生成 hashCode
}
5. 常见问题
5.1 equals() 和 == 的区别
| 方法 | 比较内容 | 适用场景 |
== | 内存地址 | 基本类型(int, char)或引用比较 |
equals() | 对象内容 | 对象比较(如 String、自定义类) |
5.2 String 的 equals() 与 equalsIgnoreCase()
equals():区分大小写。
equalsIgnoreCase():不区分大小写。
示例:
String s1 = "Hello";
String s2 = "hello";
System.out.println(s1.equals(s2)); // false
System.out.println(s1.equalsIgnoreCase(s2)); // true
5.3 数组的 equals()
数组的 equals() 默认比较地址,应使用 Arrays.equals():
int[] arr1 = {1, 2, 3};
int[] arr2 = {1, 2, 3};
System.out.println(arr1.equals(arr2)); // false
System.out.println(Arrays.equals(arr1, arr2)); // true
6. 总结
equals() 用于比较对象内容,默认比较地址,需重写。
- 重写规则:自反、对称、传递、一致、非空。
- 必须同时重写
hashCode(),否则影响哈希集合的行为。
- 推荐使用
Objects.equals() 和 Objects.hash() 避免 NullPointerException。
正确使用 equals() 可以确保对象比较的准确性和一致性,是 Java 编程的重要基础。