• hashCode()


    哈希表对学习计算机的人来说再熟悉不过了,在很多地方为了提高查找效率都会使用hash函数。在Java的Object类中有一个方法:

    public native int hashCode();

    根据这个方法的声明可知,该方法返回一个整型的数值,并且是本地方法,因此在Object类中并没有给出具体的实现。

    一、hashCode方法的作用

    在Java中hashCode()的主要作用是为了配合基于散列的结合一起正常运行。这样的散列集合包括HashSet、HashMap、HashTable。

    大多数人都会想到调用equals方法逐个进行比较,这个方法确实可行。但是如果数据量过大,效率是一个不得不考虑的问题。此时hashCode方法就体现出来了。当集合中要添加新的对象或元素时,先调用hashCode方法,得到对应的hashCode值。实际上在HashMap的具体实现中会用一个table保存已经存进去的对象的hashCode值,如果table中没有该hashCode值,它就可以直接存进去,不需要进行任何比较了;如果存在该hashCode值,就调用equals方法与新元素进行比较,相同的话就不存了,不相同就散列其他的地址。实际上Java中的hashCode方法就是根据一定的规则将与对象相关的信息(对象的存储地址、对象的字段等)映射成一个数值,这个数值称为散列值。下面这段代码就是java.util.HashMap中的put方法的具体实现: 

     1 public V put(K key, V value) {
     2         if (key == null)
     3             return putForNullKey(value);
     4         int hash = hash(key.hashCode());
     5         int i = indexFor(hash, table.length);
     6         for (Entry<K,V> e = table[i]; e != null; e = e.next) {
     7             Object k;
     8             if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
     9                 V oldValue = e.value;
    10                 e.value = value;
    11                 e.recordAccess(this);
    12                 return oldValue;
    13             }
    14         }
    15  
    16         modCount++;
    17         addEntry(hash, key, value, i);
    18         return null;
    19     }

    put方法是用来向HashMap中添加新的元素,从Put方法的具体实现可知,会先调用hashCode方法得到该元素的hashCode值,然后查看table中是否存在该hashCode值,如果存在则调用equals方法重新确定是否存在该元素,如果存在,则更新value值,否则将 新的元素添加到HashMap中。从这里可以看出,hashCode方法的存在是为了减少equals方法的调用次数,从而提高程序效率。

    二、equals方法和hashCode方法

    在有些情况下,程序设计者在设计一个类的时候需要重写equals方法,比如String类。但千万要注意:重写equals方法的同时,必须重写hashCode方法。

    -----》在程序执行期间只要equals方法的比较操作作用到的信息没有被修改,那么对同一个对象调用多次,hashCode方法必须始终如一的返回同一个整数。

    -----》如果两个对象根据equals方法比较时相等的,那么调用两个对象的hashCode方法必须返回相同的整数结果。

    -----》如果两个对象根据equals方法比较时不等的,那么hashCode方法不一定返回不同的整数。

  • 相关阅读:
    RocketMQ源码分析:(二)消息发送的三种方式
    LTS本地搭建详述
    Mac端解决(含修改8.0.13版的密码):Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
    flink入门:01 构建简单运行程序
    rocketmq控制台搭建(rocketmq-console)
    在consul上注册web服务
    将filenames里的每个字符串输出到out文件对象中注意行首的缩进
    spidermark sensepostdata ntp_monlist.py
    HTTP Error 403没有了,但是中文全都是乱码。又是怎么回事?
    original.txt和提交的页面输出的文字的混合文件
  • 原文地址:https://www.cnblogs.com/Peng-Yankee/p/8635399.html
Copyright © 2020-2023  润新知