SparseArray介紹
首先說一下SparseArray是什么東西,在java中我們也沒見過這個API啊,哦,原來是android中定義的一個類,按字面意思來說是一個稀疏數組,但通過源碼注釋我們發現它和數組有很大的區別:
SparseArrays map integers to Objects. Unlike a normal array of Objects, * there can be gaps in the indices. It is intended to be more memory efficient * than using a HashMap to map Integers to Objects, both because it avoids * auto-boxing keys and its data structure doesn't rely on an extra entry object * for each mapping.
我們通過這段注釋大體知道,android希望我們用SparseArray在一些情況下代替HashMap來使用,因為它有更好的性能,大家都知道內存是非常寶貴的,尤其是在手機上。
再看一下它的兩個構造函數:
/**
* Creates a new SparseArray containing no mappings.
*/
public SparseArray() {
this(10);
}
/**
* 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;
} 發現其默認的key-value數組大小是10,當然也可以是自定義的。
SparseArray中有一些和HashMap中相似的實用方法,比如:
put(int key, E value) get(int key) get(int key, E valueIfKeyNotFound) delete(int key) removeAt(int index) keyAt(int index) valueAt(int index) 等等。
隨便分析一個方法,比如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++;
}
} 代碼中首先查詢該key在SparseArray中是否已經存在,若存在,替換掉,若不存在,把對應的key和value插入到對應的數組中,然后mSize++。大家注意到在查詢key時使用的折半查找,看源碼:
class ContainerHelpers {
// This is Arrays.binarySearch(), but doesn't do any argument validation.
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
}
static int binarySearch(long[] array, int size, long value) {
int lo = 0;
int hi = size - 1;
while (lo <= hi) {
final int mid = (lo + hi) >>> 1;
final long 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
}
} 哇哦,是不是我們在java中常用的一種查找方式。
知道了這些之后,我們以后就可以使用SparseArray來代替HashMap了,但是要注意SparseArray中的key是int類型,若實際中不是int類型,還得乖乖的使用map,另外,根據key-value中的value類型不同,android又給封裝了SparseIntArray,SparseBooleanArray,SparseLongArray等等,使用方法和SparseArray都大同小異,只要你會使用Map,那么你就會使用SparseArray。
本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!