1. 程式人生 > >SparseArray的常用方法解析

SparseArray的常用方法解析

Android中關於SparseArray使用

通常情況下,當我們用HashMap儲存資料時,Android studio會建議我們使用SparseArray,最近公司專案使用到了,所以就來探究一下

構造器

1.無參構造器:SparseArray(),原始碼如下:
/**
 * Creates a new SparseArray containing no mappings.
 */
public SparseArray() {
    this(10);
}
2.帶參構造器:SparseArray(int initialCapacity),原始碼如下:
/**
 * Creates a new SparseArray containing no mappings that will not
 * require any additional memory allocation to store the specified
 * number of mappings.  If you supply an initial capacity of 0, the
 * sparse array will be initialized with a light-weight representation
 * not requiring any additional array allocations.
 */
public SparseArray(int initialCapacity) {
    if (initialCapacity == 0) {
        mKeys = EmptyArray.INT;
        mValues = EmptyArray.OBJECT;
    } else {
        mValues = ArrayUtils.newUnpaddedObjectArray(initialCapacity);
        mKeys = new int[mValues.length];
    }
    mSize = 0;
}
從構造器看,有兩個構造器,一個是你自己設定容器大小,一個是預設,預設值為10

下面著重看看它的幾個方法

一.新增鍵值對

1.public void put(int key, E value) ,原始碼如下:
/**
 * Adds a mapping from the specified key to the specified value,
 * replacing the previous mapping from the specified key if there
 * was one.
 */
public void put(int key, E value) {
    int i = ContainerHelpers.binarySearch(mKeys, mSize, key);

    if (i >= 0) {
        mValues[i] = value;
    } else {
        i = ~i;

        if (i < mSize && mValues[i] == DELETED) {
            mKeys[i] = key;
            mValues[i] = value;
            return;
        }

        if (mGarbage && mSize >= mKeys.length) {
            gc();

            // Search again because indices may have changed.
            i = ~ContainerHelpers.binarySearch(mKeys, mSize, key);
        }

        mKeys = GrowingArrayUtils.insert(mKeys, mSize, i, key);
        mValues = GrowingArrayUtils.insert(mValues, mSize, i, value);
        mSize++;
    }
}
2.public void append(int key, E value) ,原始碼如下:
/**
 * Puts a key/value pair into the array, optimizing for the case where
 * the key is greater than all existing keys in the array.
 */
public void append(int key, E value) {
    if (mSize != 0 && key <= mKeys[mSize - 1]) {
        put(key, value);
        return;
    }

    if (mGarbage && mSize >= mKeys.length) {
        gc();
    }

    mKeys = GrowingArrayUtils.append(mKeys, mSize, key);
    mValues = GrowingArrayUtils.append(mValues, mSize, value);
    mSize++;
}
可以看出,採用的是二分法儲存,儲存資料是按鍵的值從小到大的順序排列的。

二.查

1.根據見鍵查詢值
public E get(int key)  //查不到時為null
public E get(int key, E valueIfKeyNotFound)  //valueIfKeyNotFound 當查不到時的預設值
原始碼如下:
/**
 * Gets the Object mapped from the specified key, or <code>null</code>
 * if no such mapping has been made.
 */
public E get(int key) {
    return get(key, null);
}

/**
 * Gets the Object mapped from the specified key, or the specified Object
 * if no such mapping has been made.
 */
@SuppressWarnings("unchecked")
public E get(int key, E valueIfKeyNotFound) {
    int i = ContainerHelpers.binarySearch(mKeys, mSize, key);

    if (i < 0 || mValues[i] == DELETED) {
        return valueIfKeyNotFound;
    } else {
        return (E) mValues[i];
    }
}
.
.
.
static int binarySearch(int[] array, int size, int value) {
    int lo = 0;
    int hi = size - 1;

    while (lo <= hi) {
        final int mid = (lo + hi) >>> 1;
        final int midVal = array[mid];

        if (midVal < value) {
            lo = mid + 1;
        } else if (midVal > value) {
            hi = mid - 1;
        } else {
            return mid;  // value found
        }
    }
    return ~lo;  // value not present
}
2.檢視某個位置的鍵:
public int keyAt(int index)
3.檢視某個位置的值:
public E valueAt(int index)
4.根據Key查詢鍵所在的位置,沒有則返回負數
public int indexOfKey(int key)
5.根據Value查詢值所在的位置,沒有則返回-1
public int indexOfValue(E value) 

三.刪除

public void delete(int key)  
public void remove(int key)
public void removeAt(int index)   

四.修改

public void setValueAt(int index, E value)  //比較常用
public void put(int key, E value)  

暫時就這樣,待補充~