zoukankan      html  css  js  c++  java
  • equals和hashcode

    equals和hashcode

    一. equals已经能实现对比的功能了,为什么还要hashCode呢?

    因为重写的equals里一般比较的比较全面且复杂,效率较低,而利用hashCode进行对比,效率较高,而且哈希算法需要hashcode
    

    二.hashCode既然效率这么高为什么还要equals呢?

    因为hashCode不完全可靠,有时候equals不成立的对象会生成相同的hashcode,我们可以总结得出:
    1.equals成立  --->   hashCode肯定相等
    	也就是用equals对比是绝对可靠的
    2.hashCode相等 --->   equals不一定成立
    	也就是hashCode不是绝对可靠
    

    2.1 equals不等而hashcode相等的例子

    public class Student {
        private String name;
        private Integer age;
        @Override
        public int hashCode {
            return name.hashCode;
        }
        @Override
        public boolean equals(Object obj) {
            if (obj == this)
                return true;
            else if (!(obj instanceof Student))
                return false;
            else {
                return this.name.equals(((Student) obj).name) 
                        && this.age.equals(((Student) obj).age);
            }
        }
    }
    //两个不同年龄姓名相同的人会有相同的hashcode值,但equals不成立
    
    public class Teacher {
        private String name;
        private Integer age;
        @Override
        public int hashCode() {
            return name.hashCode();
        }
        @Override
        public boolean equals(Object obj) {
            if (obj == this)
                return true;
            else if (!(obj instanceof Student))
                return false;
            else {
                return this.name.equals(((Student) obj).name)
                        && this.age.equals(((Student) obj).age);
            }
        }
    }
    //名字相同的老师和学生hashcode将会相同,但equals不成立
    

    三.hashCode和equals的使用

    对于需要大量的对比,如果都用equals去做效率太低,解决方法是
    首先用hashCode去对比
    	如果hashCode不同,则这两个对象肯定不相等(也不必再用equals了)
    	如果hashCode相同使用equals
    		如果equals也成立,则表示这两个对象是真的相同,这样能在保证对比正确性的前提下大大提高效率
    
    这个处理方法应用在HashSet,HashMap,HashTable等容器中
    比如HashSet里要求对象不能重复,则他要对添加进去的每个对象进行对比,对比规则如上所说,先对比hashCode,如果相同,再用equals验证,如果hashCode都不同,则两对象肯定不同,省去了equals,提升了效率
    

    四.什么时候需要重写hashcode和equals方法

    一句话总结
    	一般的地方不需要重载hashCode,只有当类需要放在HashTable、HashMap、HashSet等hash结构容器内时才需要重载hashCode和equals
    
    如果我们的自定义类对象需要放进hashSet,并发挥hashSet的特性(即不包含一样的对象),则我们就要重写我们类的hashCode和equals方法了.否则默认的继承自Object的hashcode和equals方法如下
    很明显因为自定义类创建对象在堆内地址永远不可能相同,所以自定义类的equals除了他本身永远不可能成立
    
    //Object.class
    @HotSpotIntrinsicCandidate
    public native int hashCode;
    //返回对象地址,是一个本地方法(native method),由jvm底层实现
    public boolean equals(Object obj) {
        return this == obj;
    }
    //比较对象地址是否相同
    

    五.为什么equals成立,hashCode就一定相等,而hashCode相等,equals却不一定成立?

    1.为什么equals相等,hashCode就一定要相等

    1.如果两个equals的对象,hashcode都不等,那么我们将永远无法找到这个值,整个哈希算法都会不成立所以equals成立,算法要求hashCode相等.
    
    2.其次我们一般是使用类中部分属性值计算hashcode,而两个equals的类一般属性值都会相同,没有道理hashcode不相同.
    

    2. 为什么hashCode相等,equals却不一定成立?

    1.首先需要明确的是并不是不想让他们具有对称性,即equals相等,hashcode相等,反之亦然,而是函数的限制导致这种目标是不可能实现的,当你使用一个函数根据一段String生成hashcode值,你很难确定这个世界是不是存在一段String跟你原本的String完全不同,但会生成相同的hashcode值(当然概率极低).
    
    2.其次我们一般是使用类中部分属性值计算hashcode,但比如Student和Teacher他们都有属性name,hashCode都以name计算,hashCode一样,但两个对象属于不同类型,所以equals应为false.
    

    六.为什么需要hashCode?

    hashcode是哈希算法的灵魂,通过hashCode可以加快查找速度.理想状态下时间复杂度为O(1)
    
  • 相关阅读:
    算法之冒泡排序(Java语言)
    算法之水仙花数(Java语言)
    md5加密解析
    Java项目中环境变量的问题
    外行码农进阶学习指导思想
    初识TCP
    const修饰符总结
    网格计算的三种体系结构概述
    虚函数的实现
    网络计算概述
  • 原文地址:https://www.cnblogs.com/INnoVationv2/p/12820417.html
Copyright © 2011-2022 走看看