其实上面的内容就已经将WeakHashMap的主要实现讲完了,但是我之前在看HashMap源码的时候,并没有对比 JDK1.7 和 JDK1.8,但是在这里发现其实WeakHashMap的实现和 JDK1.7 差不多,所以接下来我将主要对比一下WeakHashMap和HashMap;
1. 容量计算在WeakHashMap和HashMap中都要求容量是2的幂,因为当容量为2的幂时,使用除留余数法计算哈希桶位置时可以使用hash % length = hash & (length-1)的性质进行优化;
// WeakHashMap int capacity = 1; while (capacity < initialCapacity) capacity <<= 1; // HashMap static final int tableSizeFor(int cap) { int n = cap - 1; n |= n >>> 1; n |= n >>> 2; n |= n >>> 4; n |= n >>> 8; n |= n >>> 16; return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1; }简单测试可以得到:
initCap = 10 50 100WeakHashMap 30 32 26
HashMap 3 3 3
代码比较简单我就不贴了,从上表也可以看到了tableSizeFor不经搞笑而且稳定;
2. 哈希计算 // WeakHashMap final int hash(Object k) { int h = k.hashCode(); h ^= (h >>> 20) ^ (h >>> 12); return h ^ (h >>> 7) ^ (h >>> 4); } // HashMap static final int hash(Object key) { int h; return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); }两种hash算法都是要避免极端的hashCode(),但是HashMap却更为透彻,因为影响哈希桶位置的只有 hash 的低位(容量2的n次方,n个低位),直接将高位与上低位,使高位 hash 参与位置计算,简洁且高效;
此外还有put方法,但是里面还牵涉红黑树,对于本文就扯得有点远了,所以暂不讲;
总结WeakHashMap是WeakReference的典型应用,在灵活应用WeakHashMap之后,如果有更为复杂的逻辑,可以直接使用Reference实现;