JavaJava服务器端编程编程语言爱好者

为什么重写equals还要重写hashcode方法

2020-12-20  本文已影响0人  迦叶_金色的人生_荣耀而又辉煌

Object类的常用方法

hashCode、equals、wait、notify、finalize、clone、toString

eqauls方法和hashCode方法

1.Object 的 hashcode 方法是本地方法,也就是用 c 或 c++ 实现的,该方法直接返回对象的内存地址,让后再转换整数。

//Object类中的hashCode写法
    public native int hashCode();

2.equals方法
规定:
1).两个对象的Hashcode值相等,但是两个对象的内容值不一定相等【存在Hash冲突的问题,比如a和97的hash值都为97】
2).两个对象的值Equals比较相等的情况下,则两个对象的Hashcode值一定相等;

//Object类中的equals写法
public boolean equals(Object obj) {
        return (this == obj);
    }

结论:
两个对象相等,则hashcode一定相等。
两个对象不等,hashcode不一定不等,也可能会相等。
hashcode相等,两个对象不一定相等。
hashcode不等,则两个对象一定不等。

JaryeEntity  t1 = new JaryeEntity("a",21);
JaryeEntity  t2 = new JaryeEntity("a",21);
System.out.println(t1.equals(t2));
结果为false,因为equals默认是比较内存地址的

我们重写了equals方法之后,为什么一定要重写hashcode?

【阿里的开发规范明确强调】关于 hashCode 和 equals 的处理,遵循如下规则:
1) 只要覆写 equals,就必须覆写 hashCode。
2) 因为 Set 存储的是不重复的对象,依据 hashCode 和 equals 进行判断,所以 Set 存储的对象必须覆
写这两个方法。
3) 如果自定义对象作为 Map 的键,那么必须覆写 hashCode 和 equals。
说明:String 已覆写 hashCode 和 equals 方法,所以我们可以愉快地使用 String 对象作为 key 来使用。

Map中若不定义hashCode和equals将会出现内存泄露演示

HashMap<HashKey2, Integer> map = new HashMap<HashKey2, Integer>(1000);
while (true) {
    // new 多个不同对象 参数都是相同的内容,但是对象的内存地址不同。
    HashKey2 p = new HashKey2("jarye", "123");
    // 如果没有重写 equals 底层默认采用==比较两个对象内存地址 强引用
    map.put(p, 1);
    counter++;
    if (counter % 1000 == 0) {
        System.out.println("map size: " + map.size());
        System.out.println("运行" + counter
                + "次后,可用内存剩余" + Runtime.getRuntime().freeMemory() / (1024 * 1024) + "MB");
    }
}
上一篇下一篇

猜你喜欢

热点阅读