浅谈Java中的hashcode方法

一,基本概念

          Java中的hashCode方法就是根据必定的规则将与对象相关的信息(好比对象的存储地址,对象的字段等)映射成一个数值,这个数值称做为散列值,即hashCode值.html

在Java的Object类中有一个方法:java

public native int hashCode();

根据这个方法的声明可知,该方法返回一个int类型的数值,而且是本地方法,所以在Object类中并无给出具体的实现。算法

有些朋友误觉得默认状况下,hashCode返回的就是对象的存储地址,事实上这种见解是不全面的,确实有些JVM在实现时是直接返回对象的存储地址,可是大多时候并非这样,只能说可能存储地址有必定关联。数组

hashCode返回的并不必定是对象的(虚拟)内存地址,具体取决于运行时库和JVM的具体实现性能


二,hashCode与equals

在Java中hashCode的实现老是伴随着equals,他们是紧密配合的,你要是本身设计了其中一个,就要设计另一个。固然在多数状况下,这两个方法是不用咱们考虑的,直接使用默认方法就能够帮助咱们解决不少问题。可是在有些状况,咱们必需要本身动手来实现它,才能确保程序更好的运做。this

对于equals,咱们必须遵循以下规则:spa

      对称性:若是x.equals(y)返回是“true”,那么y.equals(x)也应该返回是“true”。设计

      反射性:x.equals(x)必须返回是“true”。code

      类推性:若是x.equals(y)返回是“true”,并且y.equals(z)返回是“true”,那么z.equals(x)也应该返回是“true”。htm

      一致性:若是x.equals(y)返回是“true”,只要x和y内容一直不变,无论你重复x.equals(y)多少次,返回都是“true”。

任何状况下,x.equals(null),永远返回是“false”;x.equals(和x不一样类型的对象)永远返回是“false”。

对于hashCode,咱们应该遵循以下规则:

      1. 在一个应用程序执行期间,若是一个对象的equals方法作比较所用到的信息没有被修改的话,则对该对象调用hashCode方法屡次,它必须始终如一地返回同一个整数。

      2. 若是两个对象根据equals(Object o)方法是相等的,则调用这两个对象中任一对象的hashCode方法必须产生相同的整数结果。

      3. 若是两个对象根据equals(Object o)方法是不相等的,则调用这两个对象中任一个对象的hashCode方法,不要求产生不一样的整数结果。但若是能不一样,则可能提升散列表的性能。

 

根据hashCode,equals所遵循的规则咱们不可贵出:

若是x.equals(y)返回“true”,那么x和y的hashCode()必须相等。

若是x.equals(y)返回“false”,那么x和y的hashCode()有可能相等,也有可能不等

能够用一张流程图来描述 hashCode,equals是如何配合使用

`

整个处理流程是:

一、判断两个对象的hashcode是否相等,若不等,则认为两个对象不等,完毕,若相等,则比较equals。

二、若两个对象的equals不等,则能够认为两个对象不等,不然认为他们相等。

三,hashcode的做用 

    对于包含容器类型的程序设计语言来讲,基本上都会涉及到hashCode。在Java中也同样,hashCode方法的主要做用是为了配合基于散列的集合一块儿正常运行,提升查找效率.这样的散列集合包括HashSet、HashMap以及HashTable

    实际场景:当向集合中插入对象时,如何判别在集合中是否已经存在该对象了?(注意:集合中不容许重复的元素存在如Set集合)

    解决办法:采用equals方法去逐一比较,效率必然是一个问题.此时就须要用hashcode和equals配置使用提升效率

    根据第二章节hashcode,equals所遵循的规则以及配合使用的流程.

当集合要添加新的对象时,先调用这个对象的hashCode方法,获得对应的hashcode值,实际上在HashMap的具体实现中会用一个table保存已经存进去的对象的hashcode值

1.    若是table中没有该hashcode值,即第一步的判断 hashcode是否相同结果为false ,表示没有与该对象相等的对象.它就能够直接存进去,不用再进行任何比较了

2.若是存在该hashcode值,进行第二步equals判断(由于根据hashcode规则不一样对象可能具备相同的hashcode值),若是为true即对象相等,存在该对象就不保存.反之false不存在保存.

下面这段代码是java.util.HashMap的中put方法的具体实现:

public V put(K key, V value) {
        if (key == null)
            return putForNullKey(value);
        int hash = hash(key.hashCode());
        int i = indexFor(hash, table.length);
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
            Object k;
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }
 
        modCount++;
        addEntry(hash, key, value, i);
        return null;
    }

    hashCode重要么?不重要,对于List集合、数组而言,他就是一个累赘,可是对于HashMap、HashSet、HashTable而言,它变得异常重要。因此在使用HashMap、HashSet、HashTable时必定要注意hashCode。对于一个对象而言,其hashCode过程就是一个简单的Hash算法的实现,其实现过程对你实现对象的存取过程起到很是重要的做用。

四:参考文献

http://www.importnew.com/18851.html

http://www.importnew.com/20381.html

相关文章
相关标签/搜索