今天把Hashmap的 java 1.8 源码看了一部分,Hashmap开始初始化的时候是一个长度为16的数组
1、每次添加元素的时候,会拿key的hash值去与数组最大index进行与运算,得到对应的数组下标,如果数组当前下标的值为null,直接添加一个node对象进数组中,如果不为null,则会在当前下标元素下进行再次判断,
2、遍历它的链表下的元素,将新元素生成一个Node对象添加到最后一个next为空的链表元素下,链表长度最大为8。如果达到8的话,会进行红黑树转化判断。
3、红黑树转化需要满足容量达到64,没有达到则进行一次扩容,在原有的基础上扩容为2倍(扩容的时候会由于长度发生变化,链表1拆2到不同的数组节点上,此时链表长度会减半)。如果容量达到64的话,则会将当前数组节点下的链表转化为红黑树,后续还要添加元素,发现该节点为红黑树就会直接添加红黑树节点了
红黑树图:
测试转化红黑树代码:
public static void main(String[] args) {
HashMap m = new HashMap();
m = transTree(0, m);
m = transTree(1, m);
m = transTree(2, m);
m = transTree(3, m);
m.put(1,"1");
// System.out.println(m.toString());
}
private static HashMap transTree(int key, HashMap m) {
for (int i= 0,nodeLength=0,capacity=16,reSizeCount=0; i<8*4; i++, nodeLength++){
int thisCapacity = capacity;
if (reSizeCount > 0){
thisCapacity = capacity << reSizeCount;
}
key = key + nodeLength * thisCapacity;
m.put(key, i);
if (nodeLength == 8){
reSizeCount++;
nodeLength = nodeLength >> 1;
}
}
return m;
}
总结:hashmap是典型的以空间换时间的数据结构。可能存在:1、仅有数组结构。2、既有数组又有链表。3、既有数组又有链表还有红黑树。