当前位置:编程学习 > JAVA >>

Thinking in Java之HashMap源码分析

   欢迎讨论、交流,转载请注明出处,3Q!

        前言
              在前面的文章中笔者就Map接口和Map接口的实现原理:内部哈希映射技术做了一个简单的

           分析,并且对hashCode方法做了一些阐述。可能有些混乱,不过理解这些是弄懂HashMap

           的前提,也能帮助我们更好的解析hashMap的源码。

        HashMap类设计
               HashMap是基于哈希表的Map接口的非同步实现,它提供所有可选的映射操作,并允许使

           用null键和null值。此集合不保证映射的顺序,特别不保证其顺序永久不变。

               首先我们先看下HashMap类的头部:


[java]
public class HashMap<K,V> 
    extends AbstractMap<K,V> 
    implements Map<K,V>, Cloneable, Serializable 

public class HashMap<K,V>
    extends AbstractMap<K,V>
    implements Map<K,V>, Cloneable, Serializable           对于它的分析就不多做解释了,AbstractMap类主要是帮助我们自定义自己的Map实现类。

            1、底层实现
                 接下来我们看看HashMap的底层是如何实现的。在这之前我们先对数据结构略作分析。

            在java语言中,最基本的结构分为两种:其一为数组,其二为模拟指针(引用)说白了就是

            链表。所有的数据类型都可以使用上述的两种来构造。

                数组的特点是:寻址容易,插入和删除困难;

                链表的特点是:寻址困难,插入和删除容易;

                思考下:我们能不能结合两者的优点,折中构造一种寻址容易,插入删除也较为容易的

           数据结构呢?答案是肯定的了。我们可以构造一种“链表散列”的数据结构,可以理解为链表

           的数组,HashMap就是基于其实现的。

             

              从图中可以看出HashMap的底层就是一个数组结构,数组中的每一项又是一个链表。那么

          究竟是不是这样呢?我们看源码吧。      

[java]
 /**
     * The table, resized as necessary. Length MUST Always be a power of two.
     */  
 transient Entry<K,V>[] table; 
 static class Entry<K,V> implements Map.Entry<K,V> { 
        final K key; 
        V value; 
        Entry<K,V> next; 
        int hash; 
 
        /**
         * Creates new entry.
         */ 
        Entry(int h, K k, V v, Entry<K,V> n) { 
            value = v; 
            next = n; 
            key = k; 
            hash = h; 
        } 
    ........... 

 /**
     * The table, resized as necessary. Length MUST Always be a power of two.
     */
 transient Entry<K,V>[] table;
 static class Entry<K,V> implements Map.Entry<K,V> {
        final K key;
        V value;
        Entry<K,V> next;
        int hash;

        /**
         * Creates new entry.
         */
        Entry(int h, K k, V v, Entry<K,V> n) {
            value = v;
            next = n;
            key = k;
            hash = h;
        }
    ...........
}
              可以看出的是HashMap里面实现了一个静态内部类Entry(记录),其重要的属性有key、value、next

          而HashMap有一个属性是Entrr的数组table。Entry就是table数组中的元素,Map.Entry就会一个键值对

          这个键值对持有指向下一个键值对的引用,如此就构成了链表了。


          2、构造方法

 

[java]
/**根据指定容量和负载因子构造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); 
 
        // Find a power of 2 >= initialCapacity  
        int capacity = 1; 
   

补充:软件开发 , Java ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,