美文网首页
java 中==和 equals 和 hashCode 的区别

java 中==和 equals 和 hashCode 的区别

作者: 有腹肌的豌豆Z | 来源:发表于2020-08-25 09:28 被阅读0次

    “==”

    • ==是运算符,用来比较两个值、两个对象的内存地址是否相等;

    “equals()”

    • equals是Object类的方法,默认情况下比较两个对象是否是同一个对象,内部实现是通过“==”来实现的。如果想比较两个对象的其他内容,则可以通过重写equals方法。
     public boolean equals(Object obj) {
            return (this == obj);
        }
    
    • 例如:String类就重写了equals方法,改成了对象的内容是否相等。
     public boolean equals(Object anObject) {
            if (this == anObject) {
                return true;
            }
            if (anObject instanceof String) {
                String anotherString = (String)anObject;
                int n = value.length;
                if (n == anotherString.value.length) {
                    char v1[] = value;
                    char v2[] = anotherString.value;
                    int i = 0;
                    while (n-- != 0) {
                        if (v1[i] != v2[i])
                            return false;
                        i++;
                    }
                    return true;
                }
            }
            return false;
        }
    

    “hashCode()”

    • hashCoed也是Object类里面的方法,返回值是一个对象的哈希码,同一个对象哈希码一定相等,但不同对象哈希码也有可能相等。
    • 如果两个对象通过equals方法比较相等,那么他的hashCode一定相等;
    • 如果两个对象的HashCode相同,不代表两个对象就相同,只能说明这两个对象在散列存储结构中,存放于同一个位置;
    每个对象都有hashcode,对象的hashcode怎么得来的呢?
    • hashcode代表对象的地址说的是对象在hash表中的位置,物理地址说的对象存放在内存中的地址。
    • 通过对象的内部地址(也就是物理地址)转换成一个整数,然后该整数通过hash函数的算法就得到了hashcode。所以,hashcode是什么呢?就是在hash表中对应的位置。
    hashcode有什么作用呢?
    • HashCode的存在主要是为了查找的快捷性,HashCode是用来在散列存储结构中确定对象的存储地址的(后半句说的用hashcode来代表对象就是在hash表中的位置)。
    • 为什么hashcode就查找的更快,比如:我们有一个能存放1000个数这样大的内存中,在其中要存放1000个不一样的数字,用最笨的方法,就是存一个数字,就遍历一遍,看有没有相同得数,当存了900个数字,开始存901个数字的时候,就需要跟900个数字进行对比,这样就很麻烦,很是消耗时间,用hashcode来记录对象的位置,来看一下。
    • hash表中有1、2、3、4、5、6、7、8个位置,存第一个数,hashcode为1,该数就放在hash表中1的位置,存到100个数字,hash表中8个位置会有很多数字了,1中可能有20个数字,存101个数字时,他先查hashcode值对应的位置,假设为1,那么就有20个数字和他的hashcode相同,他只需要跟这20个数字相比较(equals),如果每一个相同,那么就放在1这个位置,这样比较的次数就少了很多,实际上hash表中有很多位置,这里只是举例只有8个,所以比较的次数会让你觉得也挺多的,实际上,如果hash表很大,那么比较的次数就很少很少了。
    equals方法和hashcode的关系?
    • 通过前面这个例子,大概可以知道,先通过hashcode来比较,如果hashcode相等,那么就用equals方法来比较两个对象是否相等。
    • 用个例子说明:上面说的hash表中的8个位置,就好比8个桶,每个桶里能装很多的对象,对象A通过hash函数算法得到将它放到1号桶中,当然肯定有别的对象也会放到1号桶中,如果对象B也通过算法分到了1号桶,那么它如何识别桶中其他对象是否和它一样呢,这时候就需要equals方法来进行筛选了。
    为什么equals方法重写的话,建议也一起重写hashcode方法?
    • 比如:有个A类重写了equals方法,但是没有重写hashCode方法,看输出结果,对象a1和对象a2使用equals方法相等,按照上面的hashcode的用法,那么他们两个的hashcode肯定相等,但是这里由于没重写hashcode方法,他们两个hashcode并不一样,所以,我们在重写了equals方法后,尽量也重写了hashcode方法,通过一定的算法,使他们在equals相等时,也会有相同的hashcode值。
    public class A {
    
        private int q=1;
        private int w=2;
    
        @Override
        public boolean equals(Object obj) {
            // 传入的对象obj 是否是A的实例
            if (obj instanceof A){
                // 因为是A的实例,所以强转为A。
                A obj1= (A) obj;
                if (this.q==obj1.q && this.w==obj1.w){
                    return true;
                }
            }
            return false;
        }
    
        public static void main(String[] arg){
            A a1=new A();
            A a2=new A();
            System.out.print(a1.hashCode()+"\n");   // 1627674070
            System.out.print(a2.hashCode()+"\n");  // 1360875712
            System.out.print(a2.equals(a1));             // true
    
        }
    
    }
    
    
    String重写hashode()
    public int hashCode() {
            int h = hash;
            if (h == 0 && value.length > 0) {
                char val[] = value;
    
                for (int i = 0; i < value.length; i++) {
                    h = 31 * h + val[i];
                }
                hash = h;
            }
            return h;
        }
    

    相关文章

      网友评论

          本文标题:java 中==和 equals 和 hashCode 的区别

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