您的位置:首页 > 其它

equals,hashCode 方法理解

2014-07-22 19:25 190 查看
一.概述(怎么判断对象相等,hashCode作用)
       在Java中,判断两个对象是否相等,先判断两个对象的hashcode是否相等,如果hashcode不等,那么认为这两个对象也不相等;如果相等,那么判断两个对象用equals是否相等,如果相等,认为两个对象也相等,否则认为两个对象不等。
      Object中的hashcode方法在我们创建对象的时候为每个对象计算一个散列码。自己定义的类也可以重写 hashcode,按照自己的方法计算散列码。(重写时简单的返回一个int值也可以,但是一般需要根据你的业务逻辑重写hashcode方法)
       数据结构有一种为了提高查找的效率而存在的数据结构——散列表,散列表其实是普通数组概念的推广,因为可以对数组进行直接寻址,故可以再O(1)时 间内访问数组的任意元素。hashcode方法的作用,它就是用来提高效率的,有句话说得好:为速度而散列。因为散列的Set和Map是基于
hashcode方法来查找对象的,所以你在使用这些类的时候一定要覆盖hashcode方法,而非散列的Set和Map,例如 TreeSet,TreeMap等,它们只需equals方法就可以唯一确定对象的身份。

二.不使用hashCode会产生的问题
       Java中的集合(Collection)有两类,一类是List,再有一类是Set。前者集合内的元素是有序的,元素可以重复;后者元素无序,但元素不 可重复。 那么这里就有一个比较严重的问题了:要想保证元素不重复,可两个元素是否重复应该依据什么来判断呢? 这就是Object.equals方法
了。但是,如果每增加一个元素就检查一次,那么当元素很多时,后添加到集合中的元素比较的次数就非常多了。 也就是说,如果集合中现在已经有1000个元 素,那么第1001个元素加入集合时,它就要调用1000次equals方法。这显然会大大降低效率。

三.利用hashCode解决上述问题
       Java采用了哈希表的原理。哈希(Hash)实际上是个人名,由于他提出一哈希算法的概念,所以就以他的名字命名了。 哈希算法也称为散列算法,是将数据依特定算法直接指定到一个地址上。
       初学者可以这样理解,hashCode方法实际上返回的就是对象存储的物理地址(实际可能并不是)。这样一来,当集合要添加新的元素时,先调用这个元素的 hashCode方法,就一下子能定位到它应该放置的物理位置上。如果这个位置上没有元素,它就可以直接存储在这个位置上,不用再进行任何比较了;如果这 个位置上已经有元素了,就调用它的equals方法与新元素进行比较(这里注意,为什么相同了还要比较呢,是因为不同的对象可能有相同的地址)相同的话就
不存了,不相同就散列其它的地址。所以这里存在一个冲突解决的问题。这样一来实际调用equals方法的次数就大大降低了,几乎只需要一两次。

四.需要注意的地方:
Java对于eqauls方法和hashCode方法是这样规定的: 

1。如果两个对象相同,那么它们的hashCode值一定要相同;
2。如果两个对象的 hashCode相同,它们并不一定相同    上面说的对象相同指的是用eqauls方法比较。  

五. Equals和hashcode的关系
 1. 对于良好的编程风格而言,你应该在重写equals()方法的同时,也重写hashCode()方法。
        如果你的对象想放进散列存储的集合中(比如:HashSet,LinkedHashSet)或者想作为散列Map(例如:HashMap,LinkedHashMap等等)的Key时,在重写equals()方法的同时,必须重写hashCode()方法。 
2. Jdk为什么希望我们在重写equals方法时,非常有必要重写hashcode方法。Hashcode是用于散列数据的快速存取,如利用 HashSet/HashMap/HashTable类来存储数据时,都是根据存储对象的hashcode值来判断是否相同。如果我们对一个对象重写了 equals方法,意思是只要对象的成员变量的值相等那么equals就返回true,但不重写hashcode方法,那么我们再new一个新的对象的时
候,当原对象.equals(新对象)等于true的时候,两者的hashcode值是不相等的。由此产生了理解上的不一致,比如在存储散列集合(如 Set类)的时候,将会存储了两个一样的对象,导致混淆,因此,也就必须重写hashcode方法。为了保证这种一致性,必须满足两个条件:
      1. 当obj1.equals(obj2)的时候。Obj1.hashCode()== obj2.hashCode() 必须为true。
      2. 当 obj1.hashcode() ==obj2.hashcode()为false的时候,obj1.equals(obj2)也必须为false。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息