zoukankan      html  css  js  c++  java
  • java的Object类中hashCode()和equals()方法-----转载

    JAVA代码:
        public static void main(String[] args)
        {
            Object obj1 = new Object();
            Object obj2= new Object();
            Object obj3 = obj2;
            System.out.println("obj1==obj2 ?"+obj1.equals(obj2));
            System.out.println("obj2==obj3 ?"+obj2.equals(obj3));
            
            System.out.println("obj1's hashcode: "+obj1.hashCode());
            System.out.println("obj1's hashcode: "+obj2.hashCode());
            System.out.println("obj1's hashcode: "+obj3.hashCode()); 
        }
    }

    输出结果:
    obj1==obj2 ?false
    obj2==obj3 ?true
    obj1's hashcode: 12677476
    obj1's hashcode: 33263331
    obj1's hashcode: 33263331

                                             总结
    API Object类中源代码:
     public boolean equals(Object obj) {
        return (this == obj);
        }
         也就是当我们写了一个自己的class,然后用class new了两个对象,如果在这两个对象上用equals时,此时比较的两个引用是不是一样,也就是他们的物理地址是不是一样,如果不一样的话,就会返回false.
        我们实际用的时候,往往不是希望比较两个对象的物理地址是不是一样,而比较两个对象的属性等东西是不是一样,所以Object提供的方法往往不能满足我们要求。
        这就需要我们覆盖Object的equals方法。

        如果要覆盖Object的equals的方法,一定要满足以下几个等价关系:
    1. 自反性,对于任何非null的引用值x,x.equals(x)必须反回true
    2. 对称性,对于任何非null的引用值x,y,当且仅当y.equals(x)返回true时,x.equals(y),才返回true.
    3. 传递性,对于任何非null的引用值x,y,z,如果x.equals(y)返回true,并且y.equals(z)返回ture,那
        么x.equals(z)也必须返回true.
    4. 一致性,对于任何非null的引用值x,y,只要equals比较操作的两个对象中所用的信息没有被修改,多次
        调用x.equals(y)就会一致的返回true,或者一致的返回false.
    5.对于任何的非null的值x,x.equals(null),必须返回false .

    如果我们的程序中没有完全遵守这些约定,那么你的程式就有可能发生问题。

    没有出问题的原因是,因为你的程序没有地方 直接调用 或者 间接调用 equals方法。
    什么是直接调用equals ,什么是间接调用equals呢?
    直接调用equals方法就是说,你显式的在你的程序中对你自己的写的对象上面调用equals方法,
    间接调用呢,用一简单的例子来说,当我们平常会把一个些对象放到collection,为了不重复,我们有调用collection的contains方法,此时就间接调用了collection中对象的equals方法。

    覆盖了equals的类中,也必须覆盖hashCode方法

    简单的结论:当对象类没有不符合规范的override equals()和hashcode()方法的时候,两个对象做比较

    1. 如果equals()比较相同,那么hashcode()肯定相同。
    2. 如果hashcode()比较相同,那么equals()不一定相同。

    众所周之,String 、Math、还有Integer、Double。。。。等这些封装类重写了Object中的equals()方法,让它不再比较句柄(引用),而是比较对象中实际包含的整数的值,即比较的是内容。

    Object的equals()方法比较的是地址值。
    一般来说,如果你要把一个类的对象放入容器中,那么通常要为其重写equals()方法,让他们比较地址值而不是内容值。特别地,如果要把你的类的对象放入散列中,那么还要重写hashCode()方法;要放到有序容器中,还要重写compareTo()方法。

    为什么要重写hashCode方法
    我们应该先了解java判断两个对象是否相等的规则。 在java的集合中,判断两个对象是否相等的规则是:

    首先,判断两个对象的hashCode是否相等 
    如果不相等,认为两个对象也不相等 
    如果相等,则判断两个对象用equals运算是否相等 
    如果不相等,认为两个对象也不相等 
    如果相等,认为两个对象相等 

    我们在equals方法中需要向下转型,效率很低,所以先判断hashCode方法可以提高效率。

    equals()相等的两个对象,hashcode()一定相等; 
    equals()不相等的两个对象,却并不能证明他们的hashcode()不相等。换句话说,equals()方法不相等的两个对象,hashcode()有可能相等。(我的理解是由于哈希码在生成的时候产生冲突造成的)。 
    反 过来:hashcode()不等,一定能推出equals()也不等;hashcode()相等,equals()可能相等,也可能不等。

     
  • 相关阅读:
    机器学习(深度学习)
    机器学习(六)
    机器学习一-三
    Leetcode 90. 子集 II dfs
    Leetcode 83. 删除排序链表中的重复元素 链表操作
    《算法竞赛进阶指南》 第二章 Acwing 139. 回文子串的最大长度
    LeetCode 80. 删除有序数组中的重复项 II 双指针
    LeetCode 86 分割链表
    《算法竞赛进阶指南》 第二章 Acwing 138. 兔子与兔子 哈希
    《算法竞赛进阶指南》 第二章 Acwing 137. 雪花雪花雪花 哈希
  • 原文地址:https://www.cnblogs.com/kaililikai/p/5887398.html
Copyright © 2011-2022 走看看