Java高频面试之SE-10
hello啊,各位观众姥爷们!!!本牛马baby今天又来了!哈哈哈哈哈嗝🐶
equals和 == 的区别?
在 Java 中,equals()
方法和 ==
运算符都是用于比较两个对象之间的相等性,但它们的工作原理和用途有明显的不同。
1. ==
运算符
- 定义:
==
是一个运算符,用于比较两个引用变量的内存地址(即它们是否指向同一个对象)。 - 用法:当使用
==
运算符比较对象时,实际上是在比较对象的引用是否相同。 - 基本数据类型:对于基本数据类型(如
int
、char
等),==
运算符比较它们的值。
示例:
String str1 = new String("Hello");
String str2 = new String("Hello");
System.out.println(str1 == str2); // 输出 false, 因为它们是不同的对象
2. equals()
方法
- 定义:
equals()
是Object
类中的一个方法,通常被重写以提供对象内容的比较。 - 用法:通常开发者在自定义类中重写
equals()
方法,以比较对象的属性值,从而实现基于内容的相等性比较。 - 默认实现:如果没有重写,
equals()
方法的默认实现与==
相同,因此会比较对象的引用。
示例:
String str1 = new String("Hello");
String str2 = new String("Hello");
System.out.println(str1.equals(str2)); // 输出 true, 因为它们的内容相同
总结
特性 | == | equals() |
---|---|---|
比较内容 | 比较引用(内存地址) | 比较对象内容(经过重写时) |
默认行为 | 是否指向同一内存地址 | 默认行为是比较引用 |
适用类型 | 基本数据类型和对象引用 | 主要用于对象,特别是重写后可比较内容 |
常见使用 | 判断是否是同一个对象 | 判断两个对象内容是否相等 |
注意事项
- 字符串比较:在比较字符串时,推荐使用
equals()
方法而不是==
,因为==
只会比较引用。 - 重写
equals()
时:如果重写了equals()
方法,通常还需要重写hashCode()
方法,以保证在散列集合(如HashMap
、HashSet
)中能正确工作。 - Null安全:在调用
equals()
方法时,应确保对象不为null
,以避免NullPointerException
。通常推荐使用Objects.equals(a, b)
方法来进行安全比较。
为什么重写 equals 时必须重写 hashCode ⽅法?
在 Java 中,当重写 equals()
和 hashCode()
方法时,确保这两个方法之间的一致性是非常重要的。这是因为它们在 Java 对象的比较和使用散列数据结构(如 HashMap
、HashSet
等)时扮演着关键角色。以下是具体原因:
1. 合同原则
Java 中 Object
类的 equals()
和 hashCode()
方法有一种关系,称为 合同原则。根据这一原则:
- 如果两个对象是相等的(即
a.equals(b)
返回true
),那么这两个对象的hashCode()
值必须相等。这意味着hashCode()
方法必须返回相同的值。 - 如果两个对象的
hashCode()
值相等,两个对象不一定相等(即a.equals(b)
不一定为true
)。这种情况是允许的,不过这是不可逆的,也就是说两个对象不同,但它们的hashCode()
值可以相同(这称为哈希冲突)。
2. 散列数据结构的性能
在 Java 的散列集合(例如 HashMap
和 HashSet
)中,对象的存储和查找依赖于哈希代码。当将对象放入一个哈希集合时,Java 首先计算对象的 hashCode()
值,以确定该对象在内部数据结构中的位置。
- 当使用
add
、remove
或contains
方法时,Java 会首先使用hashCode()
方法来找到可能存储该对象的桶(bucket)。如果两个对象的hashCode()
值不同,它们必然被放在不同的桶中,Java 会在不同的桶中寻找。 - 如果重写了
equals()
方法而没有重写hashCode()
方法,那么两个相等的对象可能会被放入相同的集合中,因为它们的hashCode()
值相同。如果检查一个对象是否存在于集合中,并且hashCode()
考虑到了该对象的状态不一致,这将导致潜在的错误。例如,两个不同的对象(基于==
的比较)可能具有相同的hashCode
,而这些对象在散列集合中可能会出现问题。
3. 可能产生的错误
假设你重写了 equals()
方法以比较对象的属性,但没有重写 hashCode()
方法,这可能会导致以下问题:
- 在
HashSet
中,如果你插入两个相等的对象,而它们的hashCode()
不同,那么即使它们是逻辑上相等的,集合仍会存储两个不同的对象。 - 在
HashMap
中,作为键的对象若基于逻辑内容重写equals()
而不重写hashCode()
,会导致存储和查找行为不一致,可能无法正确找到或更新与某个键关联的值。
示例demo
以下是一个demo,展示如何在重写 equals()
方法时,也要重写 hashCode()
方法:
public class Person {
private String name;
private int age;
// 重写 equals 方法
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof Person)) return false;
Person other = (Person) obj;
return this.name.equals(other.name) && this.age == other.age;
}
// 重写 hashCode 方法
@Override
public int hashCode() {
int result = name.hashCode();
result = 31 * result + age;
return result;
}
}
总的来说重写 equals()
方法时必须重写 hashCode()
,以确保遵循 Java 语言关于对象比较的合同原则,维护哈希结构的正确性和性能。
IDEA ji huo
https://pan.quark.cn/s/4216736c0427
🎬大全
https://kdocs.cn/l/cqhxNU9I2lLD
12306回家科技
https://pan.quark.cn/s/45f6bf9be1b3