您的位置:首页 > 其它

equals()和hashCode()隐式调用时的约定详解

2016-03-23 17:32 351 查看
不知道你听说过md5没有,它就是一种典型的hash算法。

我们用它加密密码。用户输入密码,服务器转换为md5密文,和存在数据库中的比对,如果相同,就视作用户输入密码正确。

很显然,这个过程中用户输入的密码如果正确,只能得到唯一的md5。

但是理论上,用户输入一个错误的md5也可能因为算出的md5和预留的一致而被视作是正确的。这种情况称之为hash碰撞(也就是数据结构课程里说的hash冲突)

equals()方法与hashCode()方法的隐式调用时的约定是:

1.如果两个对象相等(equals),那么他们必须拥有相同的哈希吗(hashCode)

2.即使两个对象拥有相同的hashCode,他们也不一定相等.



 

首先,我们来看一个问题.

 

[java] view
plaincopy

 

 

import java.util.HashMap;  

   

public class Apple {  

    private String color;  

   

    public Apple(String color) {  

        this.color = color;  

    }  

   

    public boolean equals(Object obj) {  

        if (!(obj instanceof Apple))  

            return false;      

        if (obj == this)  

            return true;  

        return this.color == ((Apple) obj).color;  

    }  

   

    public static void main(String[] args) {  

        Apple a1 = new Apple("green");  

        Apple a2 = new Apple("red");  

   

        //hashMap stores apple type and its quantity  

        HashMap<Apple, Integer> m = new HashMap<Apple, Integer>();  

        m.put(a1, 10);  

        m.put(a2, 20);  

        System.out.println(m.get(new Apple("green")));  

    }  



从上文代码不难看出,HashMap已保存一个"green"的Apple对象,但是,,在执行时,会发生一个问题,,,用map获取"Apple"对象时,并未找到。

然而,进入breakpoint调试时,可在变量内看见map中apple的散列码,说明已正常存入。



然而,为什么会造成这问题呢,,,这就是本文主旨所在。

---是由于hashCode()引起,因为没有重写hashCode()方法.

equals()方法与hashCode()方法的隐式调用时的约定是:

1.如果两个对象相等(equals),那么他们必须拥有相同的哈希吗(hashCode)

2.即使两个对象拥有相同的hashCode,他们也不一定相等.

Map的核心思想就是可以比线性查找更快. 通过散列值(hash)作为键(key)来定位对象的过程分为两步:
在Map内部,存储着一个顶层数组,顶层数组的每个元素指向其他的数组,查找或存储的时候,先根据key对象的hashCode()值计算出数组的索引,然后到这个索引找到所指向的第二层线性数组,使用equals方法来比较是否有相应的值(以返回或者存储).
Object类中的hashCode()默认为每个对象返回不同的int值,因此在上面的例子中,两个相等(equal)的对象,返回了不同的hashCode值.
解决方法是为此类添加hashCode方法,比如,使用color字符串的长度作为示范:

public int hashCode(){  

    // 此种实现,要求 color值定以后就不得修改  

    // 否则同一个物理对象,前后有两个不同的hashCode,逻辑上就是错的。  

    return this.color.length();   



 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  hashcode equals