`

为什么 hashcode 基数要选31

    博客分类:
  • java
 
阅读更多

原文:http://blog.csdn.net/ghsau/article/details/21328203

 

前几天被人问到了hashcode如何实现,说实话,真的是没有自己写过,通常情况下都会通过IDE自动生成,惭愧。今天研究了下hashcode的生成原理,首先看一下String类中的hashCode方法:

  1. public int hashCode() {  
  2.        int h = hash;  
  3.        if (h == 0 && value.length > 0) {  
  4.            char val[] = value;  
  5.   
  6.            for (int i = 0; i < value.length; i++) {  
  7.                h = 31 * h + val[i];  
  8.            }  
  9.            hash = h;  
  10.        }  
  11.        return h;  
  12.    }  

       核心的算法就是中间的for循环,假如字符串是"abcde",那最终的hash值应该是31(31(31(31a+b) + c) + d) + e,扩号展开为a*31^4+b*31^3+c*31^2+d*31^1+e*31^0,设字符串的长度为n,那最终的计算公式 为:s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1],这实际上就是31进制数转成10进制数的算法。那为什么要用31作为基数呢?
       我想可能有几点原因:31首先是一个素数,与素数相乘运算后,能降低hashcode碰撞的概率;31其次是一个特殊的值(32-1),32的二进制是 100000,31的二进制是011111,31*N = N << 5 - N,运算速度会快。
       普通类覆盖hashCode方法也可以使用类似的算法,如:

  1. @Override  
  2.     public int hashCode() {  
  3.         final int prime = 31;  
  4.         int result = 1;  
  5.         result = prime * result  
  6.                 + ((firstname == null) ? 0 : firstname.hashCode());  
  7.         result = prime * result  
  8.                 + ((lastname == null) ? 0 : lastname.hashCode());  
  9.         result = prime * result  
  10.                 + ((nickname == null) ? 0 : nickname.hashCode());  
  11.         return result;  
  12.     }  

       属性如果是引用类型,要与其hashCode运算,属性如果是byte、short、int类型,要与其值运算,属性如果是float、double、long,要经过特殊运算,可以参考对应封装类的hashCode方法实现。

     

分享到:
评论

相关推荐

    HashCode的用法详解

    为什么需要重写 hashCode()?因为我们需要确保对象的唯一性。如果我们不重写 hashCode(),那么对象的 hashCode 将会默认使用 Object 类中的 hashCode 方法,这样将会导致对象的存储位置不确定。 例如,如果我们有两...

    深入 HashCode 方法~

    - `Hashtable` 在计算 `HashCode` 时,会将 `HashCode` 的值与 `0x7FFFFFFF` 进行按位与操作,以确保结果为正整数。 - 进一步地,计算出的 `HashCode` 会通过模运算 `% hs.length` 来确定实际的数组索引位置。 4....

    java中的hashcode

    Java中的hashCode 在Java中,hashCode是Object类中的一个方法,它的作用是返回对象的哈希码值。哈希码值是一个整数,它可以用于在哈希表中快速地定位对象。然而,实际上,hashCode根本不能代表object的内存地址。 ...

    定义hashcode时使用31系数的原因

    本文将详细介绍为什么在定义hashcode时使用31系数的原因,以及相关的知识点。 首先,需要了解为什么需要hashcode。在Java中,每个对象都有一个默认的hashcode,但是这个默认的hashcode是无法满足实际需求的。因此,...

    hashcode的作用

    - 良好的 `hashCode()` 实现可以帮助减少不必要的内存占用。这是因为如果对象的 `hashCode()` 实现得当,可以避免过多的哈希冲突,从而减少链表的长度,进而减少内存的消耗。 #### 三、HashCode的具体实现 1. **...

    java中Hashcode的作用.docx

    但是Hashcode是什么?它是如何产生的?有什么作用?下面我们就来详细探讨Java中Hashcode的作用。 Hashcode的约定 在Java中,Hashcode的约定是由Java.lang.Object类中的hashCode方法所规定的。这个方法规定了...

    重写equals和hashcode方法_equals_重写equals和hashcode方法_

    在Java编程语言中,`equals()` 和 `hashCode()` 方法是Object类中的两个核心方法,所有类都默认继承自Object类。这两个方法在处理对象比较和集合操作时起着至关重要的作用。当我们创建自定义类并需要对对象进行精确...

    equals与hashCode方法讲解

    equals 与 hashCode 方法讲解 equals 方法和 hashCode 方法是 Java 语言中两个重要的方法,它们都是在 Object 类中定义的。equals 方法用于比较两个对象是否相等,而 hashCode 方法用于返回对象的哈希码。 在 Java...

    深入HashCode

    `hashCode()`的主要目的是为对象提供一种唯一的标识,这个标识可以快速地与其他对象进行比较。在哈希表中,`hashCode()`被用来计算对象存储的位置,因为哈希表通过对象的哈希值来确定其存储位置,从而实现快速查找。...

    hashCode的作用

    ### hashCode的作用 在Java编程语言中,`hashCode`方法是一个重要的概念,主要用于对象的查找与存储,尤其是在集合框架中有着广泛的应用。为了更好地理解`hashCode`的作用及其在实际开发中的重要性,我们可以从以下...

    为什么重写equals方法,还必须要重写hashcode方法

    为什么重写equals方法,还必须要重写hashcode方法

    hashcode和equals方法

    equals()和hashcode()这两个方法都是从object类中继承过来的。当String 、Math、还有Integer、Double。。。。等这些封装类在使用equals()方法时,已经覆盖了object类的equals()方法.

    学习Object类——为什么要重写equeals和hashcode方法

    为什么需要重写 equals 和 hashCode 方法? 在 Object 类中,equals 方法的原始实现是: public boolean equals(Object obj) { return (this == obj); } 这个方法是比较两个对象的内存地址,而不是逻辑内容。...

    为什么String的hashCode选择31作为乘子.docx

    图文并茂吃透面试题,看完这个,吊打面试官,拿高薪offer!

    关于HashCode码的重复问题 两种验证实例

    1,如果两个对象相同,那么它们的hashCode值一定要相同; 2,如果两个对象的hashCode相同,它们并不一定相同 上面说的对象相同指的是用eqauls方法比较。 3,HashCode码不唯一

    PPT浅析hashcode

    PPT浅析hashcode定义和作用;和简单的代码演示PPT.很简单的

    Java_重写equals()和hashCode()

    这就是为什么在设计类时,重写这两个方法是至关重要的,尤其是在实现集合类的元素或键值对时。 总之,理解并正确重写 `equals()` 和 `hashCode()` 方法对于编写高质量的Java代码至关重要,这直接影响到对象比较的...

    HashCode相同equals不同的2位字符集合算法

    这个问题在处理自定义类对象时尤为关键,特别是当这些对象包含可变元素,如字符集合时。 首先,让我们理解这两个方法的基本概念: 1. **hashCode()**:这个方法是Object类中的,返回一个整数值,代表对象的哈希码...

    hashCode的理解

    java中hashCode()的理解

    Java中equals,hashcode和==的区别

    hashcode 方法可以将一个对象转换为一个整数值,以便于对象的存储和比较。通常情况下,hashcode 方法需要和 equals 方法一起使用,以确保两个对象的散列码相同,如果它们的内容相同。 例如,在 HashSet 中,我们...

Global site tag (gtag.js) - Google Analytics