今天简单研究一下 ArrayMap;
ArrayMap
ArrayMap 是一种相较于 HashMap 具有更高内存效率的 key-value 对存储结构;ArrayMap 内部包括两个数组结构,分别是专门用来存储 HashCode 的 mHashes 和用来存储 key-value 的 Object 数组类型的 mArray;
ArrayMap 是非线程安全的;
源码分析
构造函数
public ArrayMap() {
this(0, false);
}
public ArrayMap(int capacity) {
this(capacity, false);
}
public ArrayMap(int capacity, boolean identityHashCode) {
mIdentityHashCode = identityHashCode;
if (capacity < 0) {
mHashes = EMPTY_IMMUTABLE_INTS;
mArray = EmptyArray.OBJECT;
} else if (capacity == 0) {
mHashes = EmptyArray.INT;
mArray = EmptyArray.OBJECT;
} else {
allocArrays(capacity);
}
mSize = 0;
}
ArrayMap 提供了三种构造方法,分别为无参的默认构造函数,添加默认容积的构造函数和一个隐藏的构造函数;若指定容积大小则直接分配相应大小的内存;若是默认构造函数,默认为 0,会在添加数据时动态扩容;
元素查询
int indexOf(Object key, int hash) {
final int N = mSize;
// ====== TAG 01 ======
int index = binarySearchHashes(mHashes, N, hash);
if (index < 0) {
return index;
}
if (key.equals(mArray[index<<1])) {
return index;
}
// ====== TAG 02 ======
for (end = index + 1; end < N && mHashes[end] == hash; end++) {
if (key.equals(mArray[end << 1])) return end;
}
for (int i = index - 1; i >= 0 && mHashes[i] == hash; i–) {
if (key.equals(mArray[i << 1])) return i;
}
return ~end;
}
ArrayMap 查找元素主要是通过 binarySearchHashes 二分查找方式来查找 index;若 HashCode 和 Key 均匹配则为要查找的 index;若只有 HashCode 相同但对象不同(即 HashCode 冲突),则从当前对应的 index 向后和向前分别遍历查找;注意:采用二分查找,则说明 mHashes 数组是有序的;
元素添加
ArrayMap 添加元素的方式主要有 put 和 append 方式;
-
put()
public V put(K key, V value) {
final int osize = mSize;
final int hash;
int index;
if (key == null) {
hash = 0;
index = indexOfNull();
} else {
hash = mIdentityHashCode ? System.identityHashCode(key) : key.hashCode();
// ====== TAG 01 ======
index = indexOf(key, hash);
}
if (index >