`
叶落黄昏
  • 浏览: 17864 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

HashCode In Java

阅读更多

很多时候,我们会使用java的hashCode在一定范围内区别对象。但是我们对java的hashCode生成规则了解多少?翻看JDK源码就可以看到我们常用的数据结构,如HashMap,ArrayList,String,Integer等类型HashCode的实现方式。

Java中的所有类的基类Object类中定义并实现了方法hashCode(),在Object类中该方法被定义成为native方法,由虚拟机的实现部分提供实现(并且注释中提到在TM版JAVA编程语言是不需要实现的),该方法返回当前对象内存地址的整数值。当我们在定义一个类型的时候,没有重载hashCode方法的情况下,我们自定类对象的hashCode方法返回的都是当前对象的内存地址。这在一些序列化和反序列化处理之后,对象的hashcode就可能不相等了,Object类实现的HashCode算法与具体的运行时环境相关,很多时候我们希望跟数据本身相关性高一点。

      Object类提供了默认的hashCode计算方式,在JDK提供的基础集合类中分别对hashCode方法进行了重载。以下分别说明一下各个基础类的hashCode的实现

1、String,对应String而言在没有重写hashCode方法的情况,一个确定的String,比如"Hello World"在不同的时候,在不同的机器上计算出来的值是不相同的。但是String重写了hashCode方法,能够保证,其hashcode值只跟所包含的字符以及字符的顺序有关系,跟计算的时间和机器本身无关,一下是String hashCode方法的实现:

     public int hashCode() {

int h = hash;

if (h == 0) {

   int off = offset;

   char val[] = value;

   int len = count;

 

            for (int i = 0; i < len; i++) {

                h = 31*h + val[off++];

            }

            hash = h;

        }

        return h;

    }

从代码中可以看到,String的hashCode计算公式为:s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1](s是该String的字符数组)。计算中使用的周期是31,显然这个周期远小于字符集合的大小,所以该hashCode没法保证所有的String对象的hashCode不冲突。

2 Integer 的hashCode不需要计算,就是它本本身,代码如下:

    public int hashCode() {

return value;

    }

3 ArrayList ArrayList的并没有自己实现hasnCode方法,而是沿用了其父类AbstractCollection实现的方法,代码如下:

    public int hashCode() {

int hashCode = 1;

Iterator<E> i = iterator();

while (i.hasNext()) {

   E obj = i.next();

   hashCode = 31*hashCode + (obj==null ? 0 : obj.hashCode());

}

return hashCode;

    }

   可以看到,代码与String的hashCode计算方式很类似。 

4、HashMap 中也没有直接实现hashCode方法,也是沿用的其父类实现的方法,代码如下

    public int hashCode() {

int h = 0;

Iterator<Entry<K,V>> i = entrySet().iterator();

while (i.hasNext())

   h += i.next().hashCode();

return h;

    }

   可以看出HashMap的hashCode值是由其包含的所有Entry对象的hashCode累加得到的,再来看看其Entry的hashCode值又是如何得来的,代码如下

      public final int hashCode() {

            return (key==null   ? 0 : key.hashCode()) ^

                   (value==null ? 0 : value.hashCode());

      }

    可以看到HashMap的Entry的hashCode值是有key的hash值与value的乘方计算得来了(有效降低冲突率)

分享到:
评论

相关推荐

    java中Hashcode的作用.docx

    "Java中Hashcode的作用" Hashcode是Java编程语言中一个非常重要的概念,它在equals方法中扮演着关键角色。在Java中,每个对象都具有一个独特的Hashcode,它可以用来标识对象的身份。但是Hashcode是什么?它是如何...

    think in java 第11章 持有对象

    8. **对象的比较**:Java中的equals()方法用于比较两个对象的内容是否相等,而hashCode()方法则与对象的唯一标识有关,常用于哈希表(如HashMap)的查找。重写这两个方法是实现自定义对象比较的关键。 9. **访问...

    Converting Array to Map in Java.zip_in

    7. **可视化辅助**:`Converting Array to Map in Java.png`可能是一个流程图或示意图,帮助理解转换过程的可视化表示。在实际编程中,这类图表有助于解释代码逻辑,特别是在团队协作或技术文档中。 8. **异常处理*...

    Java安全-Kcon研究课题 Magic In Java Api.pdf

    ### Java安全-Kcon研究课题 Magic In Java API #### 概述 本次研究主要围绕Java API中的潜在安全隐患展开,尤其关注了API的安全性及其对应用程序的影响。文档内容涉及多个方面,包括API简介、安全影响分析、RASP...

    Bug模式 - Bug Pattern In Java

    在编程世界中,Java是一种广泛使用的面向对象的语言,它的健壮性和安全性深受开发者喜爱。然而,即便是这样的语言,程序员也可能由于一些常见的编程习惯或错误理解而导致各种问题,这些错误模式通常被称为“Bug模式...

    Java教程补充材料

    10 The Methods in the Object Class (finalize, hashcode, clone, getClass, equals) 11 Hiding Data Fields and Static Methods 12 Initialization Blocks 13 Extended Discussions on Overriding Methods 14...

    Java-Reflection-and-Object-Comparison-in-Java:Java Reflection创建适当的对象,覆盖equal和hashCode方法

    空构造函数定义公共方法void setIntValue(int iIn){...}定义公共方法void setStringValue(String sIn){...}按照以下方式设计Java类:2个私有数据成员double DoubleValue ; int IntValue; 空构造函数定义公共...

    java全集.pdf JAVA全集

    - **高性能**:虽然Java最初被认为是解释型语言,但随着JIT(Just-In-Time)编译器的发展,Java的性能得到了显著提升。 **1.2 运行原理** Java程序的执行过程大致分为以下几个步骤: 1. 编写源代码并保存为`.java`...

    java笔试题

    ### Java笔试题详解 #### 一、Try-Catch-Finally机制 在Java中,`try-catch-finally`是用于处理异常的一种结构。其主要作用是确保即使在发生异常的情况下,程序也能正常运行并优雅地处理错误。 1. **无论是否出现...

    SUN Java 考试大纲

    - **Object类介绍**:分析`Object`类作为所有类的基类的重要性,介绍`equals()`、`hashCode()`等常用方法。 - **包装类**:了解Java为基本数据类型提供的包装类,如`Integer`、`Double`等。 #### 八、高级类特征 -...

    基于URL的Java网络编程

    - `int hashCode()`:创建一个适合哈希表索引的整数。 - `URLConnection openConnection()` 和 `URLConnection openConnection(Proxy proxy)`:打开一个连接到URL所引用资源的连接。 3. **通过URL读取指定文件** ...

    Java测试题2答案

    下列程序中构造了一个SET并且调用其方法add(),输出结果是 public class A{ public int hashCode(){return 1;} public Boolean equals(Object b){return true} public static void main(String ...

    JAVA经典教材笔记

    - Object类的方法:toString、hashCode等。 - **包装类** - 包装类的作用:将基本类型包装为对象。 - 常用包装类:Integer、Double等。 - **匿名内部类** - 匿名内部类的定义:没有名称的内部类。 - 匿名内部类...

    Java编程思想4_习题答案

    《Java编程思想4_习题答案》是一份珍贵的学习资源,专为正在研读 Bruce Eckel 的经典著作《Thinking in Java》第四版的读者提供。这本书深入浅出地讲解了Java编程语言的核心概念和高级特性,是Java学习者的重要参考...

    java.lang研究

    `Object`类是所有Java类的根,它定义了所有对象共有的行为,如`equals()`、`hashCode()`和`toString()`方法。`System`类提供了系统级的服务,如标准输入、输出流,以及全局变量`out`、`err`和`in`。 `Thread`类是多...

    Java程序员必会的程序

    通过实例化Person类并调用其方法,例如equals()、hashCode()、toString()和compareTo(),可以深入了解OOP的精髓。这些方法在比较对象状态、提供对象描述以及实现排序时至关重要。 #### 3. 设计模式 熟悉设计模式能...

Global site tag (gtag.js) - Google Analytics