IdentityHashMap数据结构
Posted june777
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了IdentityHashMap数据结构相关的知识,希望对你有一定的参考价值。
也是比较古老的类了,看了下源码,该类结构的简单记录。
IdentityHashMap是保存到一个Object[]数组里,不一样的是比如key的索引为0,那么value保留紧跟着的位置上,而且相同索引会顺序往下排,循环时索引的自增是+2。具体看源码
public V put(K key, V value) {
final Object k = maskNull(key);
retryAfterResize: for (;;) {
final Object[] tab = table;
final int len = tab.length;
//索引
int i = hash(k, len);
找到相同的值,注意判断的地方是==,而不是equals。
for (Object item; (item = tab[i]) != null;
i = nextKeyIndex(i, len)) {
if (item == k) {
@SuppressWarnings("unchecked")
V oldValue = (V) tab[i + 1];
tab[i + 1] = value;
return oldValue;
}
}
//没有找到相同的值,要把新值加到数组中
//先把长度+1
final int s = size + 1;
// Use optimized form of 3 * s.
// Next capacity is len, 2 * current capacity.
//3s 如果大于长度,就扩容,成功的话就继续循环,直到3s <= len了 或者扩容失败
if (s + (s << 1) > len && resize(len))
continue retryAfterResize;
//操作数+1
modCount++;
//新的i位置放key
tab[i] = k;
//i+1 放value
tab[i + 1] = value;
size = s;
return null;
}
}
private static int nextKeyIndex(int i, int len) {
//索引+2
return (i + 2 < len ? i + 2 : 0);
}
private boolean resize(int newCapacity) {
// assert (newCapacity & -newCapacity) == newCapacity; // power of 2
//扩成2倍
int newLength = newCapacity * 2;
Object[] oldTable = table;
int oldLength = oldTable.length;
if (oldLength == 2 * MAXIMUM_CAPACITY) { // can't expand any further
if (size == MAXIMUM_CAPACITY - 1)
throw new IllegalStateException("Capacity exhausted.");
return false;
}
if (oldLength >= newLength)
return false;
//创建新数组
Object[] newTable = new Object[newLength];
//旧数组开始复制,下表子增量为2
for (int j = 0; j < oldLength; j += 2) {
Object key = oldTable[j];
if (key != null) {
Object value = oldTable[j+1];
//清空原数组的key和value
oldTable[j] = null;
oldTable[j+1] = null;
//计算新数组下表
int i = hash(key, newLength);
//找到可以放值的索引
while (newTable[i] != null)
i = nextKeyIndex(i, newLength);
//放key
newTable[i] = key;
//放value
newTable[i + 1] = value;
}
}
table = newTable;
return true;
}
以上是关于IdentityHashMap数据结构的主要内容,如果未能解决你的问题,请参考以下文章
java中key值可以重复的map:IdentityHashMap
java:Map借口及其子类HashMap五,identityHashMap子类
java.util.IdentityHashMap#hash(Object x, int length)为什么总是返回2的倍数?