HashMap源码学习

 

HashMap线程不安全,键和值可以为空,HashTable线程安全,键和值不能为空

HashMap 采用数组加链表在JDK1.8之前,1.8之后采用数组加链表加红黑树

默认容量16

HashMap为什么默认容量为16不是15

2Keyhash值为8,9

容量为16

8  &16-1

1000 & 1111 =1000——》8号位置

9  &16-1

1001 & 1111 =1001——》9号位置

容量为15

8  &15-1

1000 & 1110 =1000——》8号位置

9  &15-1

1001 & 1110 =1000——》8号位置

出现hash冲突

浪费所有Key的末位为1

2的次方比较好

Java底层是使用c语言的,c语言底层是汇编(汇编使用的是16进制),汇编来源机器语言(01010101

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)

                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);

                        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;

                }

            }

            if (e != null) { // existing mapping for key

                V oldValue = e.value;

                if (!onlyIfAbsent || oldValue == null)

                    e.value = value;

                afterNodeAccess(e);

                return oldValue;

            }

        }

        ++modCount;

        if (++size > threshold)

            resize();

        afterNodeInsertion(evict);

        return null;

}

,当链表长度大于7时将链表转换成红黑树

大于等于8的情况下已经转为红黑树?

树化后节点不足8个?

1.6个时转换成链表

  1. 按照链表方式检索

目的:提高操作效率

链表

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

        final int hash;

        final K key;

        V value;

        Node<K,V> next;

......

红黑树

static final class TreeNode<K,V> extends LinkedHashMap.Entry<K,V> {

        TreeNode<K,V> parent;  // red-black tree links

        TreeNode<K,V> left;

        TreeNode<K,V> right;

        TreeNode<K,V> prev;    // needed to unlink next upon deletion

        boolean red;

......

扩容

15

1001010101原来hash

     11111 现在在31

1 15+16=31

0 15

 

posted @ 2018-10-16 15:02  dahyin  阅读(120)  评论(0编辑  收藏  举报