hashcode与equals详解

来源:互联网 发布:js添加dom resize事件 编辑:程序博客网 时间:2024/06/05 19:51

博文来源 http://www.cnblogs.com/xiohao/p/4199446.html

hashcode与equals区别与联系

equals(Object)与hashcode()方法在Object类中定义的,因此所有的对象都继承了该方法。

equals方法用于判断两个对象是否相同。hashcode返回的是一个整数int,将对象的内部地址转换为一个整数返回。

规范1:若重写equals方法,有必要重写hashcode方法,确保通过equals方法判断结果为true的两个对象具备相等的hashcode返回值。

规范2:若equals方法false,即两个对象不相同,并不要求对这两个对象调用hashcode方法得到两个不同的数。

推论:1、若两个对象equals,Java运行环境会认为他们的hashcode一定相等。2、若两个对象不equals,他们的hashcode可能相等。3、若两个对象的hashcode相等,它们不一定equals。4、若两个对象的hashcode不相等,它们一定不equals。

由hashcode和equals的区别对HashSet和HashMap的联系

HashSet要求不能存储相同的对象,HashMap要求不能存储相同的键。  

定义一个类,重写这两个方法

class A {          @Override       public boolean equals(Object obj) {           System.out.println("判断equals");           return false;       }       @Override       public int hashCode() {           System.out.println("判断hashcode");           return 1;       }   }   public class f01 {public static void main(String[] args) { Map<A,Object> map = new HashMap<A, Object>();           map.put(new A(), new Object());           map.put(new A(), new Object());               System.out.println(map.size());}}
打印的结果是判断hashcode 判断hashcode 判断equals 2

分析:第一次map.put(new A(), new Object())时,Java运行环境会判断map里面有没有此时添加的new A()对象的相同的键,调用new A()对象的hashcode()方法,判断map中是不是存在new A()对象相同的HashCode。显然此时map没有东西,所以没有必要调用equals(Object)方法(推论4)。当第二次调用map.put(new A(), new Object())时,Java运行环境再次判断,此时发现map中存在两个两同的HashCode(这里是由于重写的方法返回值永远是1),所以调用equals(Object)方法进行判断(推论3).然后发现两个对象不equals(由于重写的方法返回值永远是false)。判断结束,判断结果是两次存入的对象时不同的对象。所以map的长度显然是2.

注:把equals的返回值改为true,map的长度就是1了。

以上就是HashMap的实现原理,先判断hashcode在判断equals。HashSet的底层本身是通过HashMap来实现的,所以判断原理与HashMap一致。


1、'=='比较的变量可以是基本类型和对象类型,基本类型时直接比较值。对象类型时比较的是两个对象在栈中的引用(即地址)(对象存在在堆中,栈中存放的是对象的引用),此时若两个对象要进行对象内容的比较应该使用equals。

2、 Object类中的equals方法就是使用'=='来进行比较的,比较的是对象的地址,若要比较对象的内容,必须重写equals方法。

3、Object类中的hashCode方法返回的是对象的内存地址转换为一个int值。所以若没有重写hashCode方法,任何对象的hashCode是不相等的。在往HashSet中添加对象时,要检查集合中是否已经存在该对象,使用hashCode方法。

4、String、Integer、Boolean、Double等类是重写了上面的两个方法,重写的方法中是根据对象的内容来比较和计算hashCode的。所以只要对象的基本类型值相同,那么hashcode就一点相同。

5、在object类中,hashcode()方法是本地方法,返回的是对象的引用(地址值),而object类中的equals()方法比较的也是两个对象的引用(地址值),如果equals()相等,说明两个对象地址值也相等,当然hashcode()也就相等了。hashcode不等,equals一定不等。hashCode相等,equals可能相等也可能不相等。equals不相等,也不等推出hashcode相不相等。


HashCode出现的原因,Java集合(Collection)有两类,一类是List一类是Set。List是有序可重复,Set是无序不可重复的。保证元素不重复使用Object。equals方法,所元素很多时,比较的次数非常多,效率很低。所以引入HashCode(哈希算法或散列表)),初学者可以理解为该方法返回的是对象存储的物理地址(实际可能并不是),这样当添加新元素时,先调用hashcode方法定位到其存放的物理地址上,若该位置没有元素则直接存储到该位置上;若该位置已经有元素则调用equals方法与新元素比较,相同就不存,不相同就散列到其他地址。

原创粉丝点击