`
java_fei
  • 浏览: 21693 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

jdk1.6源码学习---HashMap和HashTabel

阅读更多

       HashMap和HashTable两个是jdk.util包下2个经常使用的类,他们都继承AbstractMap抽象类,该抽象类实现了Map接口

     原理 :hashMap和HashTable是根据key的hashcode来直接定位数组中的每个下标值,这样就不用进行for循环,然后因为不同的key会产生相同的hashcode,在同个table[i]下标下有多个。key-value这样的Entry,所以在Entry中又有一个next成员变量对这些Entry实现一个链表形式。如图:

 
     hashMap:首先HashMap的组成是一个数组加链表 的结构,也可以理解为数组里面的每个元素其实是一个链表,即a->b->c,通过a来获得b,b可以获得c,在hashMap中使用的key-value的模式,这种模式其实是封装在一个object当中,在这个object中有2个成员变量一个是key,一个是value。当然在hashMap中这个object的类真实名称是Entry在hashmap中的674行,在Entry中存放的有四个值:key value next hash //key即hashMap中的key,value即对应的值,next即链表中的下一个Entry对象,hash是每个key的hashcode(在内存中hashcode代表的是key是内存中存放的地址).   

     在hashMap中有三个构造函数,当然无非是几个之间相互调用而已:最主要的一个构造函数如下:

    //initialCapaity:传入的hashMap参数,loadFactor:对于hashMap的空间和时间效率因素
    public HashMap(int initialCapacity, float loadFactor) {
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal initial capacity: " +
                                               initialCapacity);
        if (initialCapacity > MAXIMUM_CAPACITY)
            initialCapacity = MAXIMUM_CAPACITY;
        if (loadFactor <= 0 || Float.isNaN(loadFactor))
            throw new IllegalArgumentException("Illegal load factor: " +
                                               loadFactor);
   
    //上面的语句都没什么用,废话,直接看下面
        int capacity = 1;
        while (capacity < initialCapacity)
            capacity <<= 1;//这里其实是一个2的平方,所以当你创建一个hashmap以为方法的第一个参数为10,以为hashmap的数组长度就是10就错了,是16

        this.loadFactor = loadFactor;
        threshold = (int)(capacity * loadFactor);//这个就是当一个hashMap中数据个数超过threshold的时候就会进行数据扩展(下面进行说明)
        table = new Entry[capacity];
        init();//jdk中保留
    }


 


   //下面介绍最重要的2个方法:其余的方法我想基本都不是什么问题了
    //首先是put方法:

    public V put(K key, V value) {
        if (key == null)//当key值为null的时候进行特定的放入数据:由此可见hashMap的key是可以为null的
            return putForNullKey(value);
        int hash = hash(key.hashCode());//获得key的hashcode
        int i = indexFor(hash, table.length);//这个是hashcode和数组长度进行与比较,这样可以使得i的值不操作数组长度并且跟hashcode是有直接相连的
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {//下面是数组中的一个table[i]确定的元素进行链表循环
            Object k;
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {//当key值原来已经存在的时候进行值替换
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }

        modCount++;//这个参数是hashmap中用来统计你对当前hashmap进行了多少次操作
        addEntry(hash, key, value, i);//这个方法是将key和value放入数组中
        return null;
    }


  //具体添加

   void addEntry(int hash, K key, V value, int bucketIndex) {
    Entry<K,V> e = table[bucketIndex];//讲table[i]中的第一个Entry传给临时变量
        table[bucketIndex] = new Entry<K,V>(hash, key, value, e);//table[i]中指向这个新创建的Entry,并将临时变量传递给next
        if (size++ >= threshold)//用来数组的扩容
            resize(2 * table.length);
    }
 


下面讲解下为什么使用threshold,默认是(数组长度/0.75)因为数组是链表形式所以数组是可以放无限个Entry(内存允许),但对于查找效率将会随着链表的长度增加而降低,所以需要在Entry个数达到一定数量的时候进行数组的扩充。


    HashTable:HashTable的原理和HashMap的原理是一样(或者说基本都是一样)的,但是看源代码可以发现,hashTable中每个方法都添加一个同步机制synchronized,也就是

hashTable是线程安全的。还有一个区别就是hashtabel中key和value值都不允许为null,具体看hashtable的方法。

     备注:我想把我看到的和分析的写下来,对自己是非常有帮助的,希望看到的朋友如果觉得有什么不对的地方能指出来,Thanks !

  • 大小: 27.6 KB
分享到:
评论
1 楼 287854442 2011-11-08  
写的很不错 顶了

相关推荐

    java-jdk1.6-jdk-6u45-windows-x64.zip

    1. 解压缩"java-jdk1.6-jdk-6u45-windows-x64.zip"文件,这将释放出"jdk-6u45-windows-x64.exe"可执行文件。 2. 双击运行"jdk-6u45-windows-x64.exe",安装向导会引导你完成安装过程。通常,你需要选择安装路径,...

    aspose-words-15.8.0-jdk1.6

    aspose-words-15.8.0-jdk1.6aspose-words-15.8.0-jdk1.6aspose-words-15.8.0-jdk1.6aspose-words-15.8.0-jdk1.6aspose-words-15.8.0-jdk1.6aspose-words-15.8.0-jdk1.6aspose-words-15.8.0-jdk1.6aspose-words-...

    jdk1.6 解压版-windows

    Java Development Kit (JDK) 是Java编程语言的核心组件,它为开发者提供了编译、调试和运行Java应用程序所需的所有工具。JDK1.6是Oracle公司发布的一个较早版本,适用于Windows操作系统。在这个解压版中,用户无需...

    jdk-1.6-windows-64-01

    2部分: jdk-1.6-windows-64-01 jdk-1.6-windows-64-02

    JDK-1.6-Windows-32位 官方

    压缩包中的文件`jdk-6u45-windows-i586.exe`是JDK 1.6更新45的Windows 32位安装程序。安装步骤通常包括: 1. 下载并运行安装程序。 2. 遵循安装向导的提示,选择安装路径和组件。 3. 设置环境变量,包括`JAVA_HOME`...

    jdk-1.6-linux-64-3

    三部分: jdk-1.6-linux-64-1 jdk-1.6-linux-64-2 jdk-1.6-linux-64-3

    jdk-1.6-linux-64-2

    三部分: jdk-1.6-linux-64-1 jdk-1.6-linux-64-2 jdk-1.6-linux-64-3

    jdk1.6-windows-x64

    在描述中,“jdk1.6 windows64版本 解压完直接双击安装即可”,意味着用户在下载该压缩包后,不需要进行复杂的设置或编译过程,只需将其解压缩,然后通过简单的鼠标操作,即双击名为“jdk-6u45-windows-x64.exe”的...

    logback-cfca-jdk1.6-3.1.0.0.jar

    logback-cfca-jdk1.6-3.1.0.0.jar

    jdk-1.6-windows-32-3

    三部分: jdk-1.6-windows-32-1 jdk-1.6-windows-32-2 jdk-1.6-windows-32-3

    jdk-1.6-linux-64-1

    三部分: jdk-1.6-linux-64-1 jdk-1.6-linux-64-2 jdk-1.6-linux-64-3

    jdk-jdk1.6.0.24-windows-i586.exe

    标题中的"jdk-jdk1.6.0.24-windows-i586.exe"是一个Java Development Kit(JDK)的安装程序,适用于Windows操作系统且为32位版本。JDK是Oracle公司提供的一个用于开发和运行Java应用程序的软件包。这个特定的版本,...

    zxing jar包,支持jdk1.6,包括源码

    - 这可能是ZXing库的完整源码包,专门针对JDK1.6编译,包含了所有必要的源文件和资源,供开发者进行更深度的定制和集成。 总之,ZXing库是一个强大的条形码和二维码工具,这个特别适配JDK1.6的版本为那些仍在使用...

    jdk1.6 源码jdk1.6 源码

    深入理解JDK 1.6的源码对于Java开发者来说至关重要,因为它揭示了语言核心库的工作原理,有助于优化代码、理解和解决潜在问题。 1. **Java虚拟机(JVM)**:JDK 1.6中的JVM是Java程序执行的基础,它的主要职责是...

    jdk1.6-windows-x64.rar

    jdk1.6安装版官方下载,JDK详细介绍 JDK(Java Development Kit) 是 Java 语言的软件开发工具包(SDK)。 SE(J2SE),standard edition,标准版,是我们通常用的一个版本,从JDK 5.0开始,改名为Java SE。 EE(J2EE),...

    JDK1.6.0.24-64位

    在安装和配置JDK 1.6.0.24时,用户需要注意环境变量的设置,特别是`JAVA_HOME`和`PATH`,确保系统能够正确找到Java命令。64位版本需要与64位操作系统兼容,以充分利用大内存优势。对于那些依赖于特定JDK版本的旧项目...

    jdk-1.6-linux-32-2

    jdk-1.6-linux-32-1 jdk-1.6-linux-32-2 jdk-1.6-linux-32-3

    Sun JDK 1.6内存管理--调优篇

    《Sun JDK 1.6内存管理--调优篇》深入探讨了Java开发中的关键环节——JVM内存管理和性能优化。Sun JDK 1.6作为早期的Java开发环境,其内存管理机制对于理解现代JVM的工作原理至关重要。本文将详细解析JVM内存结构,...

    Jdk1.6-linux-x64

    运行这个文件时,通常需要赋予它执行权限(例如,使用`chmod +x jdk-6u34-linux-x64.bin`命令),然后通过终端执行它来启动安装过程。 另一个文件是"linux-jdk安装说明.txt",这提供了一个详细的指南,指导用户如何...

    jdk1.6 源代码--part2

    自己整理的完整版jdk1.6的source,包含了jdk包中原先的src.zip,自己重新压缩过。可以直接使用解压后的src.zip 完全解压后的代码有138M 方便调试跟踪 分了2部分,这是第二部分

Global site tag (gtag.js) - Google Analytics