HashMap(jdk1.8)

来源:互联网 发布:godaddy域名续费好贵 编辑:程序博客网 时间:2024/06/07 16:33

1.类声明:

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

2.变量:

//默认初始化容量    static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16    //最大容量    static final int MAXIMUM_CAPACITY = 1 << 30;    //默认加载因子     static final float DEFAULT_LOAD_FACTOR = 0.75f;     //对于table里面的每个列表,从链表结构转为红黑树结构的阈值     static final int TREEIFY_THRESHOLD = 8;     //对于table里面的每个列表,从红黑树结构转为列表结构的阈值     static final int UNTREEIFY_THRESHOLD = 6;     //最小树化容量。只有当表的容量达到这个阈值,才能从列表结构转为树结构     static final int MIN_TREEIFY_CAPACITY = 64;     //当改变了表的映射数目(put方法增加了新的Node节点)或者修改了表结构(remove(),clear())的时候,进行+1,若是对map进行迭代的时候,发生modCount不是期望的modCount,即被修改了,则抛出ConcurrentModificationException异常      transient int modCount;

3.方法:

//找到不小于cap的最小的2的n次方,这个算法之精辟令人叹为观止。具体可见参考文章1。通过右移使得cap-1表示的二进制数每一位都变成1。最后加1得到所需数。  static final int tableSizeFor(int cap) {        int n = cap - 1;        n |= n >>> 1;        n |= n >>> 2;        n |= n >>> 4;        n |= n >>> 8;        n |= n >>> 16;        return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;    }    //put方法      public V put(K key, V value) {        return putVal(hash(key), key, value, false, true);    }    //若onlyIfAbsent为true,不会覆盖掉旧值,若为false,会覆盖掉旧值     final V putVal(int hash, K key, V value, boolean onlyIfAbsent,                   boolean evict) {        Node<K,V>[] tab; Node<K,V> p; int n, i;        if ((tab = table) == null || (n = tab.length) == 0)            n = (tab = resize()).length;        if ((p = tab[i = (n - 1) & hash]) == null)            tab[i] = newNode(hash, key, value, null);        else {            Node<K,V> e; K k;            if (p.hash == hash &&                ((k = p.key) == key || (key != null && key.equals(k))))                e = p;            else if (p instanceof TreeNode)//如果是TreeNode节点                e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);            else {//如果是链表节点                for (int binCount = 0; ; ++binCount) {                    if ((e = p.next) == null) {                        p.next = newNode(hash, key, value, null);//往链表尾部插入节点,jdk7是往链表头部插入节点。                        //当链表数量大于树化阈值时,进行树化操作,对应的当remove的时候会有一个链表化的操作                        if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st                            treeifyBin(tab, hash);                        break;                    }                    if (e.hash == hash &&                        ((k = e.key) == key || (key != null && key.equals(k))))                        break;                    p = e;                }            }            //如果找到了旧的数据,则根据onlyIfAbsent值决定是否更新            if (e != null) { // existing mapping for key                V oldValue = e.value;                if (!onlyIfAbsent || oldValue == null)                    e.value = value;                afterNodeAccess(e);                return oldValue;            }        }        ++modCount;//当增加了新的node时,修改次数+1        if (++size > threshold)            resize();        afterNodeInsertion(evict);        return null;    }    //往树结构中插入数据     final TreeNode<K,V> putTreeVal(HashMap<K,V> map, Node<K,V>[] tab,                                       int h, K k, V v) {            Class<?> kc = null;            boolean searched = false;            TreeNode<K,V> root = (parent != null) ? root() : this;            for (TreeNode<K,V> p = root;;) {                int dir, ph; K pk;                if ((ph = p.hash) > h)                    dir = -1;                else if (ph < h)                    dir = 1;                else if ((pk = p.key) == k || (k != null && k.equals(pk)))                    return p;                else if ((kc == null &&                          (kc = comparableClassFor(k)) == null) ||                         (dir = compareComparables(kc, k, pk)) == 0) {                    if (!searched) {                        TreeNode<K,V> q, ch;                        searched = true;                        if (((ch = p.left) != null &&                             (q = ch.find(h, k, kc)) != null) ||                            ((ch = p.right) != null &&                             (q = ch.find(h, k, kc)) != null))                            return q;                    }                    dir = tieBreakOrder(k, pk);                }                TreeNode<K,V> xp = p;                if ((p = (dir <= 0) ? p.left : p.right) == null) {                    Node<K,V> xpn = xp.next;                    TreeNode<K,V> x = map.newTreeNode(h, k, v, xpn);                    if (dir <= 0)                        xp.left = x;                    else                        xp.right = x;                    xp.next = x;                    x.parent = x.prev = xp;                    if (xpn != null)                        ((TreeNode<K,V>)xpn).prev = x;                    moveRootToFront(tab, balanceInsertion(root, x));                    return null;                }            }        }

参考文章:1.http://blog.csdn.net/fan2012huan/article/details/51097331
2.http://blog.csdn.net/crazy1235/article/details/75579654

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 小孩脖子睡歪了怎么办 脸部三角区肿了怎么办 面部三角区挤了怎么办 胳膊扭着了肿了怎么办 多囊卵巢综合症治不好怎么办 胳膊受了风发麻怎么办 胳膊抻筋了很疼怎么办 腰抻了怎么办最有效 孩子胳膊抻着了怎么办 胳膊伤筋了疼怎么办 宝宝胳膊抻了疼怎么办 练完普拉提头晕怎么办 生完孩子腰背疼怎么办 宝宝不肯把屎尿怎么办 存的电话删除了怎么办 脚踝的韧带断了怎么办 买了双鞋子想退怎么办 鞋子大了一码怎么办 nba篮球大师身体素质满了怎么办 钉鞋大了一码怎么办 篮球鞋鞋垫会向里面跑怎么办 穿高跟鞋脚肿了怎么办 衣服弄到单车油怎么办 高低床孩子摔下来怎么办 量血压时老紧张怎么办 牛仔外套的扣子掉了怎么办 裤子的裤筒大了怎么办 衣服拉链驰坏了怎么办 小脚裤裤腿紧了怎么办 地垫粘地板了怎么办 棉麻衬衣皱了怎么办 麻料衣服烫皱了怎么办 在京东买一双奥康鞋没有防伪怎么办 足球鞋丁掉了一颗怎么办 鼻子有点大想变小该怎么办 阿勒泰小东沟风景区边防证怎么办 孩子上一年级了学习很差怎么办 孩子作息时间不规律怎么办 冬天冻脸怎么办小妙招 冬天冻脚怎么办小妙招 冬天脚冷怎么办小妙招