代码语言: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