Java基础高频面试
✅== 与 equals 区别
==
运算符
- 用于基本类型时,比较变量存储的数值是否相等。
- 用于引用类型时,比较堆内存地址是否相同(即是否为同一对象)。
equals()
方法
- 默认继承自
Object
类,与==
作用相同(比较地址)。 - 但许多类(如
String
、Integer
)重写了equals()
,改为比较对象内容是否相同。
同理如果是我们自定义的类,需要我们自己重写 equals,否则使用 equals 得到的结果都是 false
@Override
public boolean equals(Object obj) {if (this == obj) return true;if (obj instanceof Student) {Student s = (Student) obj;return this.age == s.age && this.name.equals(s.name); }return false;
}System.out.println(stu1 == stu2); // false(不同地址)
System.out.println(stu1.equals(stu2)); // true(因为重写了equals方法)
✅hashCode() 与 equals 的关系
Java规范要求——等同对象必须哈希相同,根据Java规范,若a.equals(b)
为true
,则a.hashCode()
必须等于b.hashCode()
。不重写hashCode()
会导致违反规则。
普通对象(不涉及 Hash 集合操作)
- 重写了 equals 没有重写 hashCode,是不会造成功能上的影响的,但是会违背规范,而且假如之后有将该对象存入 HashSet、HashMap 的键之类的操作,就会因哈希码不一致导致数据重复存储或查找失败。
普通对象(涉及 Hash 集合操作)
- 重复存储:
HashSet
可能存储多个内容相同的对象,破坏集合的唯一性。 - 查找失败:即使
equals
返回true
,因哈希码不同,集合无法定位对象,导致contains()
或get()
失败。
举个例子:
HashSet 的 add 操作:
- 第一步:计算哈希值,调用对象的
hashCode()
方法,确定该元素在哈希表中的存储位置(桶)。 - 第二步:比较哈希值:
- 若目标桶为空,直接存储。(由于没有重写 hashCode(),可能导致本该重复的对象,他们的 hash 值不同,从而直接视为不同的元素,跳过后面的 equals() 方法)
- 若目标桶非空,再调用
equals()
比较桶内所有元素内容是否相同:
-
- 若存在
equals
为true
的元素,视为重复,拒绝存储。 <
- 若存在