hash

2022-01-10 16:46:25 浏览数 (1)

代码语言:javascript复制
//Hashmap解析
Map<String, Object> map = new HashMap<>();
map.put("key1",value1);
map.put("key2", value2);

//以上代码在初始化map是会先调用hashmap中的hash()方法,且hashmap的初始数据结构为数组加链表的结构体系
 static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }
//通过key的值计算出相应的数组下标
static class Node<K,V> implements Map.Entry<K,V> {
        final int hash;
        final K key;
        V value;
        Node<K,V> next;

        Node(int hash, K key, V value, Node<K,V> next) {
            this.hash = hash;
            this.key = key;
            this.value = value;
            this.next = next;
        }
        ........
}
//而此时出现hash冲突,即不同的值通过hashcode的计算出统一的hash值
//根据链表的结构将相同的下标的节点存入数组
//此时hashmap和hashtable在存入数组下标都调用了indexfor方法
//HashMap 
static int indexFor(int h, int length) {
   return h & (length-1);
}
//HashTable
int index = (hash & 0x7FFFFFFF) % tab.length;

//可以看出hashmap和hashtable在获取hash整型后存入的数组下标的地址的获取方法存在差异

//hashmap存在最坏情况,即所有的值通过hash整数与数组长度的位运算存入的index下标相同
//此时hashmap表变为纯链表,hashmap转变为红黑树
/**
 * 桶的树化阈值:
 *     即 链表转成红黑树的阈值,在存储数据时,
 *     当链表长度 > 该值时,则将链表转换成红黑树
 */
static final int TREEIFY_THRESHOLD = 8;

/**
 * 桶的链表还原阈值:
 *     即 红黑树转为链表的阈值,当在扩容(resize())时
 *     (此时HashMap的数据存储位置会重新计算),在重新计算存储位置后,
 *     当原有的红黑树内数量 < 6时,则将 红黑树转换成链表
 */
static final int UNTREEIFY_THRESHOLD = 6;

/**
 * 最小树形化容量阈值:
 *     即 当哈希表中的总容量 > 该值时,才允许将链表转换成红黑树,
 *     否则,当元素太多时,则直接扩容,而不是树形化
 *     为了避免进行扩容、树形化选择的冲突,这个值不能小于 4 * TREEIFY_THRESHOLD
 */
static final int MIN_TREEIFY_CAPACITY = 64;

本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名,转载请标明出处 最后编辑时间为: 2021/10/14 07:43

0 人点赞