ArrayMap 笔记整理

源码基于 API 25

主要参考文章:面试必备:ArrayMap源码解析


1、概述

在这里插入图片描述在这里插入图片描述

截图自:面试必备:ArrayMap源码解析

在开始讲解源码之前,需要说明 ArrayMap 的底层实现结构,即两个数组:

int[] mHashes; // 用于存储 key 对应的 hash 值
Object[] mArray; //  根据映射规则,用于存储 key 和 value

其中,mHashes 按照 hash 值的大小从到大排序,这样就可以实现二分查找。

假设对于某一 key,有对应的 hash 值 X,如果 X 在 mHashes 中对应的下标为 index,则对于 mArray,mArray[index<<1] 存储着 key,mArray[(index<<1)+1] 存储着 value。

因此,mArray 的长度是 mHashes 的两倍。


2、成员及构造函数

// 用于缓存数组用的,后面会说到
static Object[] mBaseCache;
static int mBaseCacheSize;
static Object[] mTwiceBaseCache;
static int mTwiceBaseCacheSize;

// 判断通过 key 生成 hash 值时是否使用特殊的方法
final boolean mIdentityHashCode;

int[] mHashes;
Object[] mArray;
int mSize;

public ArrayMap() {
   
    this(0, false);
}

/**
 * Create a new ArrayMap with a given initial capacity.
 */
public ArrayMap(int capacity) {
   
    this(capacity, false);
}

/** {@hide} */
public ArrayMap(int capacity, boolean identityHashCode) {
   
    mIdentityHashCode = identityHashCode;
    // If this is immutable, use the sentinal EMPTY_IMMUTABLE_INTS
    // instance instead of the usual EmptyArray.INT. The reference
    // is checked later to see if the array is allowed to grow.
    if (capacity < 0) {
   
        mHashes = EMPTY_IMMUTABLE_INTS;
        mArray = EmptyArray.OBJECT;
    } else if (capacity == 0) {
   
        mHashes = EmptyArray.INT;
        mArray = EmptyArray.OBJECT;
    } else {
   
    	// allocArrays() 方法用于构建指定容量的 mHashes 和 mArray
        allocArrays(capacity);
    }
    mSize = 0;
}

/**
 * Create a new ArrayMap with the mappings from the given ArrayMap.
 */
public ArrayMap(ArrayMap<K, V> map) {
   
    this();
    if (map != null) {
   
        putAll(map);
    }
}

3、成员方法

3.1 增

对于成员方法,其中,我认为 put(K key, V value) 方法是最先需要理解的,理解了 put(),其他的就好理解了。

public V put(K key, V value) {
   
    final int hash;
    int index;
    // 得到 key 的 hash 值,进一步的到该 hash 在 mHashes 中对应的 index
    if (key == null) {
   
        hash = 0;
        index = indexOfNull();
    } else {
   
    	// 根据 mIdentityHashCode 判断怎样生成 key 对应的 hash 值
        hash = mIdentityHashCode ? System.identityHashCode(key) : key.hashCode();
        // indexOf() 方法用于根据 key 以及其 hash 值得到在 mHashes 中对应的 index
        index = indexOf(key, hash);
    }
    // 如果 index >= 0,表示 key 已经存在,则直接替换对应位置的 value
    if (index >= 0) {
   
        index = (index<<1) + 1;
        final V old = (V)mArray[index];
        mArray[index] = value;
        return old;
    }
    // 否则,该 key 原本没有,是需要新增的
    // 因此 ~index 为需要新增插入的位置
    index = ~index;
    if (mSize >= mHashes.length) {
   
        // 如果已经满了,则需要扩容
        final int n = mSize >= (BASE_SIZE*2) ? (mSize+(mSize>>1))
                : (mSize >= BASE_SIZE ? (BASE_SIZE
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值