`

String类中的hashCode()分析

    博客分类:
  • JAVA
阅读更多

hashCode()这个方法是Object中定义的,因此,不管Java中的每个类都会显示或者隐含的调用hashCode。本文将从以下几个方面对hashCode进行阐述。

  • 什么是hashcode?
  • JDK中String类中的hashCode的详细定义;
  • 简单阐述一下为什么hashCode的系数为31;

 

  1. 什么是hashcode?

    维基百科的定义:In the Java programming language, every class implicitly or explicitly provides a hashCode() method, which digests the data stored in an instance of the class into a single hash value (a 32-bit signed integer). This hash is used by other code when storing or manipulating the instance – the values are intended to be evenly distributed for varied inputs in order to use in clustering. This property is important to the performance of hash tables and other data structures that store objects in groups ("buckets") based on their computed hash values.

    hashcode其实就是对象存在内存中的一个索引,指示对象应该存在哪个位置,根据这个位置可以取出这个对象,但是它必须要减少冲突,并且在存储和操作的时候尽可能高效。

 

     2. JDK中String类中的hashCode的详细定义

 

     

 /** The value is used for character storage. */
    private final char value[];

    /** The offset is the first index of the storage that is used. */
    private final int offset;

    /** The count is the number of characters in the String. */
    private final int count;

    /** Cache the hash code for the string */
    private int hash; // Default to 0

 

/**
     * Returns a hash code for this string. The hash code for a
     * <code>String</code> object is computed as
     * <blockquote><pre>
     * s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
     * </pre></blockquote>
     * using <code>int</code> arithmetic, where <code>s[i]</code> is the
     * <i>i</i>th character of the string, <code>n</code> is the length of
     * the string, and <code>^</code> indicates exponentiation.
     * (The hash value of the empty string is zero.)
     *
     * @return  a hash code value for this object.
     */
    public int hashCode() {
	int h = hash;
        int len = count;
	if (h == 0 && len > 0) {
	    int off = offset;
	    char val[] = value;

            for (int i = 0; i < len; i++) {
                h = 31*h + val[off++];
            }
            hash = h;
        }
        return h;
    }

 String类覆盖了Object类中的hashCode方法,从代码的注释中可以看得出,一个String的对象的hashCode值的计算方法为:s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]。其中,s[i]表示是第i个字符,n是字符串的长度。这里是取字符的ASC2码的值进行计算的。

 

    3.为什么hashCode的系数为31?

       前面介绍过hashcode是为了存储和操作的时候更高效,hash算法有个通用的毛病就是会冲突,为了让冲突的概率更低,研究表明,使用素数作为系统,他们冲突的概率会比使用合数的冲突的概率低得多。至于为什么选择31而不是别的素数,我就无从得知啦。

分享到:
评论

相关推荐

    JAVA入门1.2.3:一个老鸟的JAVA学习心得 PART1(共3个)

    1.4.1 类(Class):Java世界中一类物体 14 1.4.2 方法(Method):物体的功能 15 1.4.3 main()方法:所有Java程序执行的起点 15 .1.5 名词解释 16 1.5.1 JDK和Java平台 16 1.5.2 Java编译器(Java Compiler)...

    Java入门1·2·3:一个老鸟的Java学习心得.PART3(共3个)

    1.4.1 类(Class):Java世界中一类物体 14 1.4.2 方法(Method):物体的功能 15 1.4.3 main()方法:所有Java程序执行的起点 15 .1.5 名词解释 16 1.5.1 JDK和Java平台 16 1.5.2 Java编译器(Java Compiler)...

    JAVA基础课程讲义

    字符串相关类(String、 StringBuffer 、 StringBuilder) 120 String类的常用方法(已讲过,不再讲!) 120 StringBuffer和StringBuilder 121 String和StringBuffer和StringBuilder使用要点 123 时间处理相关类 124...

    javaSE代码实例

    13.3.1 弥补String不足的StringBuffer类 253 13.3.2 编写方法链以及StringBuffer类的重要方法 255 13.4 StringBuilder类 258 13.5 正则表达式 259 13.5.1 正则表达式的基本语法 259 13.5.2 Pattern类简介...

    Java入门教程(微学苑)-part1

    3.24.1.2 2) 通过 import 语句引入包中的类 57 3.25 类的路径 57 3.26 包的访问权限 58 3.27 源文件的声明规则 59 3.28 一个简单的例子 59 4 Java继承和多态 61 4.1 继承的概念与实现 61 4.2 Java super关键字 63 ...

    java8集合源码分析-Outline:大纲

    集合源码分析 JAVA: 基本语法 static 修饰变量 方法 静态块(初始化块 构造函数 ) 静态内部类() 静态导包 final() transient() foreach循环原理() volatile底层实现() equals和hashcode(, ) string,stringbuffer和...

    基于javatcpsocket通信的拆包和装包源码-someData:存放一些思维导图,图片,ppt等等

    String类的研究,String可以被继承吗,为什么不可变,在虚拟机内存中是怎么存储的 String,StringBuffer,StringBuilder的区别,多线程下的优缺点,从源代码分析 对象的三大特性 接口和抽象类的区别,使用场景 类的...

    sesvc.exe 阿萨德

    Entry 是 HashMap 中的一个内部类,从他的成员变量很容易看出: key 就是写入时的键。 value 自然就是值。 开始的时候就提到 HashMap 是由数组和链表组成,所以这个 next 就是用于实现链表结构。 hash 存放的是当前...

    疯狂JAVA讲义

    9.3.2 String、StringBuffer和StringBuilder类 322 9.3.3 Math类 327 9.3.4 Random类 328 9.3.5 BigDecimal类 330 9.4 处理日期的类 333 9.4.1 Date类 333 9.4.2 Calendar类 334 9.4.3 TimeZone类 337 9.5 ...

    基于javatcpsocket通信的拆包和装包源码-java-interview:java基础知识点

    equals()&==&hashCode()&Object&hashMap String 和 StringBuffer的区别 Collection&Collections区别 hashSet如何保证不重复 什么是线程同步 进程 和 线程 Lock 和 Synchronized 的区别 常见的内存溢出 重载和重写的...

    asp.net模板引擎Razor中cacheName的问题分析

    本文实例讲述了asp.net模板引擎Razor中cacheName的问题。分享给大家供大家参考。具体如下: 一、为什么使用cacheName 使用cacheName主要是考虑到Razor.Parse()每解析一次都会动态创建一个程序集,如果解析量很大,就...

Global site tag (gtag.js) - Google Analytics