}
return null;
}
在get的时候,我们首先会根据我们的key去计算它的hash值,如果这个hash值不存在,我们直接反回null。
如果存在,在没有发生hash冲突的情况下也就是根据当前hash值计算出的索引上的存储数据不是以树和链表的形式存储的时候,我们直接返回当前索引上存储的值,如果时链表树,我们就去遍历节点上的数据通过equals去比对,找到我们需要的在返回。
通过上面我可以得出结论,当HashMap没有发生hash冲突时,hashMap的查找和插入的时间复杂度都是O(1),效率时非常高的。
当我们发生扩容和hash冲突时,会带来一定性能上的损耗。
HashMap大致分析完了。
下面我们来分析分析Android为我们提供的ArrayMap和SparseArray。
二.我们在来看看ArrayMap:
public class ArrayMap<K, V> extends SimpleArrayMap<K, V> implements Map<K, V> {
MapCollections<K, V> mCollections;
int[] mHashes;
Object[] mArray;
通过源码我们可以看到ArrayMap继承自SimpleArrayMap实现了Map接口,ArrayMap内部是两个数组,一个存放hash值,一个存放Obeject对象也就是value值,这一点就和HashMap不一样了。我们现来看看ArrayMap的构造方法:
public ArrayMap(int capacity) {
super(capacity);
}
public SimpleArrayMap() {
mHashes = ContainerHelpers.EMPTY_INTS;
mArray = ContainerHelpers.EMPTY_OBJECTS;
mSize = 0;
}
我们发现ArrayMap的初始化会给我们初始化两个空数组,并不像HashMap一样为我们默认初始化了一个大小为16的table数组,下面我们继续往下看:
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 = key.hashCode();
index = indexOf(key, hash);
}
if (index >= 0) {
index = (index<<1) + 1;
final V old = (V)mArray[index];
mArray[index] = value;
return old;
}
index = ~index;
if (osize >= mHashes.length) {
-
final int n = osize >= (BASE_SIZE*2) ? (osize+(osize>>1))
- (osize >= BASE_SIZE ? (BASE_SIZE*2) : BASE_SIZE);
if (DEBUG) Log.d(TAG, "put: grow from " + mHashes.length + " to " + n);
final int[] ohashes = mHashes;
final Object[] oarray = mArray;
allocArrays(n);
if (CONCURRENT_MODIFICATION_EXCEPTIONS && osize != mSize) {
throw new ConcurrentModificationException();
}
if (mHashes.length > 0) {
if (DEBUG) Log.d(TAG, “put: copy 0-” + osize + " to 0");
System.arraycopy(ohashes, 0, mHashes, 0, ohashes.length);
System.arraycopy(oarray, 0, mArray, 0, oarray.length);
}
freeArrays(ohashes, oarray, osize);
}
if (index < osize) {
if (DEBUG) Log.d(TAG, "put: move " + index + “-” + (osize-index)
- " to " + (index+1));
System.arraycopy(