美文网首页JavaJava服务器端编程编程语言爱好者
为什么重写equals还要重写hashcode方法

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

作者: 迦叶_金色的人生_荣耀而又辉煌 | 来源:发表于2020-12-20 08: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");
        }
    }
    

    相关文章

      网友评论

        本文标题:为什么重写equals还要重写hashcode方法

        本文链接:https://www.haomeiwen.com/subject/hfqggktx.html