--和equals区别
一、 Java 中的对象相等判断(核心重点)
1. 基本原则:==vsequals()
==:比较内存地址。判断两个引用是否指向堆内存中的同一个对象。适用场景:判断是否为
null,或明确需要判断是否为单例/同一实例时。
equals():比较内容。默认情况下,Object类的equals()方法就是用==实现的,所以必须重写才能比较内容。
2. 正确重写equals()和hashCode()
这是 Java 面试的必考点。如果重写equals()却不重写hashCode(),在使用HashMap或HashSet时会出大问题。
标准写法(模板):
@Override public boolean equals(Object o) { // 1. 同一性检查:引用相同直接返回 true if (this == o) return true; // 2. 空值检查 + 类型检查 if (o == null || getClass() != o.getClass()) return false; // 3. 类型转换 User user = (User) o; // 4. 比较关键字段(注意处理空指针) return age == user.age && Objects.equals(name, user.name); } @Override public int hashCode() { // 使用 Objects.hash 自动生成哈希值 return Objects.hash(name, age); }3. 工具类推荐(强烈推荐)
手动重写容易遗漏字段,建议使用工具库:
Apache Commons Lang:
EqualsBuilder.reflectionEquals(obj1, obj2)Lombok: 使用
@EqualsAndHashCode注解自动生成。Google Guava:
Objects.equal(obj1, obj2)
4. 深度比较(Deep Equals)
如果对象内部包含了其他对象(如List<User>),需要确保内部的对象也重写了equals(),否则只会比较 List 的内存地址。
二、 JavaScript / Vue 中的对象相等判断
1. 引用比较 vs 内容比较
const obj1 = { a: 1 }; const obj2 = { a: 1 }; obj1 === obj2; // false (引用不同) JSON.stringify(obj1) === JSON.stringify(obj2); // true (但有坑)2. 浅比较(Shallow Compare)
仅比较对象的第一层属性。
适用场景: Vue 的
computed属性依赖、React 的PureComponent。实现:
function shallowEqual(obj1, obj2) { const keys1 = Object.keys(obj1); const keys2 = Object.keys(obj2); if (keys1.length !== keys2.length) return false; return keys1.every(key => obj1[key] === obj2[key]); }
3. 深比较(Deep Compare)
递归比较所有层级的属性。
注意: 自己写递归函数容易遇到循环引用(A 包含 B,B 包含 A)导致栈溢出。
推荐方案: 使用Lodash 的
_.isEqual(obj1, obj2)。这是最稳妥的方案。
4. Vue 响应式对象的特殊情况
在 Vue 3 中,如果使用reactive()创建的对象,直接比较可能会失效,因为它们被 Proxy 包装了。
建议: 比较它们的原始值,或者使用 Vue 提供的工具函数。
三、 避坑指南(全栈必看)
场景 | 错误做法 | 正确做法 |
|---|---|---|
Java 比较 BigDecimal |
|
|
Java 比较 String |
|
|
JS 比较对象 |
|
|
JS 比较数组 |
|
|
集合比较 |
| 确保集合内的元素也重写了 |
💡 面试/实战话术
场景一:Java 后端
“在判断对象相等时,我从不使用
==。如果是普通的 DTO,我会使用Lombok 的@EqualsAndHashCode 注解来生成方法,避免手写出错。如果是BigDecimal 这种高精度数值,我会特意使用compareTo而不是equals,因为equals会比较精度(比如 1.0 和 1.00 会被认为不相等)。”
场景二:前端/Vue
“在 Vue 中比较对象,我通常避免使用
JSON.stringify,因为它对函数、循环引用和属性顺序都很敏感。对于简单的配置对象,我用浅比较;对于复杂的表单数据对象,我直接使用Lodash 的_.isEqual,确保递归比较所有层级的数据,防止漏判。”
总结:
Java: 重写
equals()+hashCode(),用工具库(Lombok/Guava)。JS: 用 Lodash 的
_.isEqual,不要自己造轮子。
