重写hashCode与equals后,为何自定义对象用==判断不相等?
我定义了一个CustomKey自定义键对象,已重写hashCode与equals方法,但测试时发现对象判断存在疑问。相关代码如下:
@Getter @Setter public class CustomKey { private int freq; private MergerType mergerType; private NoiseRemovalType removalNoise; public CustomKey(int freq, MergerType mergerType, NoiseRemovalType removalNoise) { this.freq = freq; this.mergerType = mergerType; this.removalNoise=removalNoise; } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof CustomKey customKey)) return false; return freq == customKey.freq && removalNoise == customKey.removalNoise && mergerType == customKey.mergerType; } @Override public int hashCode() { return Objects.hash(freq, mergerType, removalNoise); } CustomKey customKey=new CustomKey(freq, MergerType.TIME_MERGER, NoiseRemovalType.REMOVE_NOISE); CustomKey key=new CustomKey(freq, MergerType.TIME_MERGER, NoiseRemovalType.REMOVE_NOISE); System.out.println(key.hashCode()); System.out.println(key.hashCode()==customKey.hashCode()); System.out.println(key.equals(customKey)); System.out.println(key); System.out.println(customKey); System.out.println(key==customKey); }
执行输出结果:
- 1370597946
- true
- true
- CustomKey{freq=1380, mergerType=TIME_MERGER, removalNoise=REMOVE_NOISE}
- CustomKey{freq=1380, mergerType=TIME_MERGER, removalNoise=REMOVE_NOISE}
- false
请问为何两个对象hashCode相同、equals返回true,但用==判断却返回false?
这是Java中==运算符和equals方法的核心区别导致的:
==运算符的作用
对于对象类型,==判断的是两个引用是否指向堆内存中的同一个对象实例,也就是检查内存地址是否完全一致。你通过new CustomKey(...)创建了两个对象,每次new都会在堆上分配新的内存空间,所以key和customKey是两个独立的对象实例,内存地址不同,因此==返回false。equals方法的作用
你重写了equals方法,它的逻辑是判断两个CustomKey对象的内容是否相等——即freq、mergerType、removalNoise三个属性的值是否完全匹配。你的两个对象属性完全一致,所以equals返回true,这符合你重写方法的预期。hashCode与equals的关系
根据Java的规范:如果两个对象通过equals判断为相等,那么它们的hashCode必须相同。你的代码遵循了这个规范,所以两个对象的hashCode相同是正常的。但反过来,hashCode相同不代表equals一定为true(可能存在哈希碰撞),不过这里是属性完全一致导致的哈希值相同,属于合理情况。
简单来说:==看的是“是不是同一个对象”,equals看的是“内容是不是一样”,你的两个对象内容相同但不是同一个实例,所以出现了这样的结果。
内容的提问来源于stack exchange,提问作者matel

