本文共 2383 字,大约阅读时间需要 7 分钟。
HashMap的原理
(JDK 1.7)HashMap是由数组+链表的形式实现的,集成了数组的获取元素方便以及链表的插入元素方便的优点,初试数组长度设置的是16位。其中HashCode代表了在hash表中的位置。并且在HashMap中有一个Hash算法 (使用异或运算) 使得链表的位置在数组中尽量均匀分布,来减少 哈希碰撞 的几率。因为计算方式使用的是位与运算,为了防止链表的位置可能多次出现在数组的第一个位置,尽量将HashMap的长度保持为2的次方数——当然在HashMap中也有相应的处理(tableSizeFor方法)来使得数组长度变成2的次方数。
出现的问题:性价比----时间和空间复杂度
@SuppressWarnings({ "rawtypes","unchecked"}) Node[] newTab = (Node [])new Node[newCap]; table = newTab; if (oldTab != null) { for (int j = 0; j < oldCap; ++j) { Node e; if ((e = oldTab[j]) != null) { //如果原有的不是空 oldTab[j] = null; if (e.next == null)//如果数组是空的,就去拿到next newTab[e.hash & (newCap - 1)] = e;//newTab进行位与运算(取余,找位置),把元素再放进去 else if (e instanceof TreeNode)//如果是棵树 ((TreeNode )e).split(this, newTab, j, oldCap);//split,打散 else { // preserve order Node loHead = null, loTail = null; Node hiHead = null, hiTail = null; Node next; do { next = e.next; if ((e.hash & oldCap) == 0) { if (loTail == null) loHead = e; else loTail.next = e; loTail = e; } else { if (hiTail == null) hiHead = e; else hiTail.next = e; hiTail = e; } } while ((e = next) != null); if (loTail != null) { loTail.next = null; newTab[j] = loHead; } if (hiTail != null) { hiTail.next = null; newTab[j + oldCap] = hiHead; } } } } } return newTab; }
Hashtable是线程安全的,因为每个操作都加了synchronized锁,但是会导致调用Hashtable的时候,如果线程一多就会堵死。所以会有下一章ConcurrentHashMap。
转载地址:http://uqugn.baihongyu.com/