Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 343|回复: 0

[Java基础知识]java中hashcode()函数的作用

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-9-30 17:48:32 | 显示全部楼层 |阅读模式
    java 对象 Hashcode 的作用是什么?可以联想数据结构的哈希表(散列表)、哈希函数。Object.hashCode() 就是一个哈希函数,用来计算散列值以实现哈希表这种数据结构。 看下哈希表结构:

       在一个数组中存储对象时,通过 hashCode 得到的哈希值来计算数组的索引位置(通常是求余运算),然后根据这个索引位置进行存取。多个对象计算出来的索引位置相同(叫hash冲突)时,用链表保存。冲突怎么保证取到的就是自己呢?那么就要用到 Object.equals() 方法。

    所以要把对象存储在像 hash table类似的数据结构(比如:HashSet)中,hashCode 与 equals 要成对实现。

    Java Object.hashCode()   返回该对象的哈希码值。支持该方法是为哈希表提供一些优点,例如,java.util.Hashtable 提供的哈希表。  hashCode 的常规协定是:  在 Java 应用程序执行期间,在同一对象上多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是对象上 equals 比较中所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。  如果根据 equals(Object) 方法,两个对象是相等的,那么在两个对象中的每个对象上调用 hashCode 方法都必须生成相同的整数结果。  以下情况不是必需的:如果根据 equals(java.lang.Object) 方法,两个对象不相等,那么在两个对象中的任一对象上调用 hashCode方法必定会生成不同的整数结果。但是,程序员应该知道,为不相等的对象生成不同整数结果可以提高哈希表的性能。    上面的协定来看,一个对象的状态(这些状态不一定是所有字段,根据业务来看)没有改变时,多次调用 hashCode 必定相等。但是不同的对象可以有相等的 hashCode,不过尽量使不同的对象有不相等的 hashCode 可以提高哈希表的性能。 看下 Java Hashtable 的 get 与 put 实现:
    1. public synchronized V get(Object key) {
    2.         Entry tab[] = table;
    3.         int hash = key.hashCode();
    4.         int index = (hash & 0x7FFFFFFF) % tab.length;
    5.         for (Entry< K,V> e = tab[index] ; e != null ; e = e.next) {
    6.             if ((e.hash == hash) && e.key.equals(key)) {
    7.                 return e.value;
    8.             }
    9.         }
    10.         return null;
    11. }
    复制代码
      先根据 key.hashCode 找数组的索引位置 index,hash & 0x7FFFFFFF 保证是正数。然后顺着找 hash 和 equals 相等的。冲突链越长性能就越差。

    看 put 方法:

    1. public synchronized V put(K key, V value) {
    2.         // Make sure the value is not null
    3.         if (value == null) {
    4.             throw new NullPointerException();
    5.         }
    6.         // Makes sure the key is not already in the hashtable.
    7.         Entry tab[] = table;
    8.         int hash = key.hashCode();
    9.         int index = (hash & 0x7FFFFFFF) % tab.length;
    10.         for (Entry< K,V> e = tab[index] ; e != null ; e = e.next) {
    11.             if ((e.hash == hash) && e.key.equals(key)) {
    12.                 V old = e.value;
    13.                 e.value = value;
    14.                 return old;
    15.             }
    16.         }
    17.         modCount++;
    18.         if (count >= threshold) {
    19.             // Rehash the table if the threshold is exceeded
    20.             rehash();
    21.             tab = table;
    22.             index = (hash & 0x7FFFFFFF) % tab.length;
    23.         }
    24.         // Creates the new entry.
    25.         Entry< K,V> e = tab[index];
    26.         tab[index] = new Entry< K,V>(hash, key, value, e);
    27.         count++;
    28.         return null;
    29. }
    复制代码
    先看是否有相同的,有就替换。然后数组空间不够,会重换分配空间并数据重新散列保存。最后在冲突链头上插入。
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-10 04:00 , Processed in 0.455356 second(s), 46 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表