JDK1.7 HashMap源码详解

文章参考:https://www.cnblogs.com/skywang12345/p/3310835.html

 1. HashMap概述

      HashMap是存储键值对内容的一个集合,继承于AbstractMap,实现了Map、Cloneable、java.io.Serializable接口,HashMap的实现不是线程同步的,即非线程安全的,key和value都是支持null的。

      HashMap根据键的hashCode值获取存储位置,存储数据,大部分情况可以直接定位到它的值,访问速度快,但是其遍历的顺序确实不确定的(无序)。

 2. HashMap存储结构

    数组: 

          数组的存储区是连续的,占用内存严重,故空间复杂度很大。但数组的二分查找时间度小;

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

    链表:

          链表的储存区离散,占用内存比较宽松,故空间复杂度很小,但时间复杂度大;

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

    哈希表

         Jdk1.7 : 数组+链表 Jdk1.8 数组+链表+红黑树 (寻址容易,插入和删除也容易)

    结构图

         

  3 HashMap成员概述

      3.1  重要的成员变量

        transient Entry[] table:是一个Entry[]数组类型,而Entry实际上是一个单向链表,哈希表中的“key-value键值对”都存储在Entry数组中,

        transient int size:是HashMap的大小,是保存HashMap中保存键值对的数量

        final float loadFactor:加载因子 

        int threshold:是HashMap的阈值,用来判断是否需要调整HashMap的容量,threshold = 容量*加载因子(最大可承受装载的容量),达到最大threshold值时,就需要扩容 

        transient volatile int modCount:fail-fast机制的需要。

        trasient

           就是让某些被修饰的成员属性变量不被序列化

        volatile

             是一个类型修饰符(type specifier)。volatile的作用是作为指令关键字, 确保本条指令不会因编译器的优化而省略, 且要求每次直接读值。 volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。

        final 

            变量不可变,被修饰后就是一个常量

         Entry[] table 源码详解

            static class Entry<K,V> implements Map.Entry<K,V> {                

                final K key;  // 成员变量

                V value; 

                Entry<K,V> next;   // 指向下一个节点 

                final int hash; 

                构造函数。 初始化操作,输入参数包括哈希值(h), 键(k), 值(v), 下一节点(n) 

                Entry(int h, K k, V v, Entry<K,V> n) { 

                    value = v; 

                    next = n; 

                    key = k; 

                    hash = h;

                } 

                public final K getKey() { 

                    return key; 

                } 

                public final V getValue() { 

                    return value;

                } 

                public final V setValue(V newValue) { 

                    V oldValue = value; 

                    value = newValue; 

                    return oldValue; 

                } 

                判断两个Entry是否相等

                先判断两个对象类型是否相等,不相同直接返回false

                相同然后判断两个Entry的key和value是否相等,相同返回true 否则false   

                public final boolean equals(Object o) { 

                    if (!(o instanceof Map.Entry))     //判断类型是否相同

                        return false;

                    Map.Entry e = (Map.Entry         //获取key和value用于判断

                    Object k1 = getKey(); 

                    Object k2 = e.getKey(); 

                    if (k1 == k2 || (k1 != null && k1.equals(k2))) { 

                        Object v1 = getValue(); 

                        Object v2 = e.getValue(); 

                    if (v1 == v2 || (v1 != null && v1.equals(v2))) 

                        return true;

                    } 

                    return false; 

                } 

                实现hashCode() 

                public final int hashCode() { 

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

                } 

                public final String toString() { 

                    return getKey() + "=" + getValue(); 

                } 

                当向HashMap中添加元素时,绘调用recordAccess(),这里不做任何处理 

                void recordAccess(HashMap<K,V> m) { } 

                当从HashMap中删除元素时,绘调用recordRemoval(),这里不做任何处理 

                void recordRemoval(HashMap<K,V> m) { }

            }

    3.2 重要的成员方法

        Object clone()

        boolean containsKey(Object key)

        boolean containsValue(Object value)

        boolean isEmpty()

        int size()

        void clear()

        void putAll(Map<? extends K, ? extends V> map)

        V put(K key, V value)

        V get(Object key)

        V remove(Object key)

        Collection<V> values()

        Set<K> keySet()

        Set<Entry<K, V>> entrySet()

    3.3 构造函数

        HashMap()默认构造函数。

        HashMap(int capacity) 指定“容量大小”的构造函数

        HashMap(int capacity, float loadFactor) 指定“容量大小”和“加载因子”的构造函数

        HashMap(Map<? extends K, ? extends V> map) 包含“子Map”的构造函数

  4 HashMap成员源码详解  (大量代码袭来)注释符号多了,看着不舒服就去了,嘿嘿   

        package java.util;

        import java.io.*;

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

       {

            默认的初始容量是16,必须是2的幂。

            static final int DEFAULT_INITIAL_CAPACITY = 16;

            最大容量(必须是2的幂且小于2的30次方,传入容量过大将被这个值替换) 

            static final int MAXIMUM_CAPACITY = 1 << 30; 

            默认加载因子       

            static final float DEFAULT_LOAD_FACTOR = 0.75f;

            存储数据的Entry数组,长度是2的幂, HashMap是采用拉链法实现的,每一个Entry本质上是一个单向链表 

            transient Entry[] table;

            HashMap的大小,它是HashMap保存的键值对的数量 

            transient int size;

            HashMap的阈值,用于判断是否需要调整HashMap的容量(threshold = 容量*加载因子) 

            int threshold;

            加载因子实际大小 

            final float loadFactor;

            HashMap被改变的次数 (fail-fast机制)

            transient volatile int modCount;

           默认构造函数。     

           public HashMap() {   

                设置加载因子

                this.loadFactor = DEFAULT_LOAD_FACTOR;     

                设置HashMap阈值,当HashMap中存储数据的数量达到threshold时,就需要将HashMap的容量加倍。 

                threshold = (int)(DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR);  

                创建Entry数组,用来保存数据 

                table = new Entry[DEFAULT_INITIAL_CAPACITY];    

                init();

             }         

           指定“容量大小”的构造函数    

           public HashMap(int initialCapacity) {  

                 this(initialCapacity, DEFAULT_LOAD_FACTOR);  

            }     

            指定“容量大小”和“加载因子”的构造函数 ,先判断参数合法性后初始化

            public HashMap(int initialCapacity, float loadFactor) {

              参数不合法抛出异常 

              if (initialCapacity < 0)        

                   throw new IllegalArgumentException("Illegal initial capacity: " +initialCapacity);

               if (initialCapacity > MAXIMUM_CAPACITY) 

                   initialCapacity = MAXIMUM_CAPACITY;

     

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值