HashMap is a common collection class in Java, and I'm used to caching some of the processed results. When I was working on an Android project recently, defining such a variable in the code and instantiating it, Eclipse gave a performance warning.
It means replacing with sparsearray<e> to get better performance. To be honest, not familiar with Sparsearray, the first feeling should be a class provided by Android. Ctrl-click to enter the source of Sparsearray, sure enough, to determine the Android provides a tool class.
Purely literally, sparsearray refers to a sparse array (Sparse array), where the so-called sparse array is the majority of the content values in the array are not used (or all 0), and only a small portion of the space is used in the array. Therefore, the memory space wasted, in order to save memory space, and do not affect the contents of the array of content values, we can use a compressed way to represent the contents of the sparse array.
Suppose there is an array of 9*7, with the following contents:
In this array, there are 63 spaces, but only 5 elements are used, resulting in a waste of 58 element space. Let's use the sparse array to redefine the array:
Where the first part of the sparse array records the number of columns and rows of the original array and the number of elements used, the second part records the position and contents of the elements in the original array. After compression, the original need to declare an array of size 63, and after using compression, only need to declare an array of size 6*3, only 18 storage space.
Continue to read the Sparsearray source code, from the construction method we can see, it and the general list, can be pre-set container size, the default size is 10:
5 |
public SparseArray( int initialCapacity) { |
6 |
initialCapacity = ArrayUtils.idealIntArraySize(initialCapacity); |
8 |
mKeys = new int [initialCapacity]; |
9 |
mValues = new Object[initialCapacity]; |
Take a look at its "additions and deletions" to the data.
It has two ways to add a key-value pair:
1 |
public void put( int key, E value) {} |
2 |
public void append( int key, E value){} |
There are four ways to perform a delete operation:
1 |
public void delete( int key) {} |
2 |
public void remove( int key) {} //直接调用的delete(int key) |
3 |
public void removeAt( int index){} |
Modifying the data initially thought that only setvalueat (int index, e value) could modify the data, but later found that the put (int key, E value) could also modify the data, and we looked at the source of the put (int key, E value), Before you put the data, you will find out whether the data you want to put already exists, and if so, add it if it exists.
1 |
public void put( int key, E value) { |
2 |
int i = binarySearch(mKeys, 0 , mSize, key); |
9 |
if (i < mSize && mValues[i] == DELETED) { |
15 |
if (mGarbage && mSize >= mKeys.length) { |
18 |
// Search again because indices may have changed. |
19 |
i = ~binarySearch(mKeys, 0 , mSize, key); |
Therefore, there are two ways to modify the data actually:
1 |
public void put(int key, E value) |
2 |
public void setValueAt(int index, E value) |
Finally, let's look at how to find data. There are two ways to query a value:
2 |
public E get(int key, E valueIfKeyNotFound) |
where get (int key) is also just called get (int key,e valueifkeynotfound), the last variable name from the argument can be seen, the incoming is not found when the return value. Get (int key) returns null by default when not found.
To view the keys in the first few places:
1 |
public int keyAt(int index) |
One thing to note is that the view key is in the same position as the binary lookup key, so the value less than 0 is returned instead of 1 if it is not found. The negative value returned is the location where it was not found.
To see the values for the first few locations:
1 |
public E valueAt( int index) |
To see where the value is, no, return-1:
1 |
public int indexOfValue(E value) |
Finally, it is found that the core is binary lookup function (binarysearch), algorithm design is very good.
1 |
private static int binarySearch( int [] a, int start, int len, int key) { |
2 |
int high = start + len, low = start - 1 , guess; |
4 |
while (high - low > 1 ) { |
5 |
guess = (high + low) / 2 ; |
13 |
if (high == start + len) |
15 |
else if (a[high] == key) |
Corresponding also have Sparsebooleanarray, used to replace Hashmap<integer, Boolean>,sparseintarray used to replace Hashmap<integer, Integer> We are interested to be able to study.
Summary: Sparsearray is a class specifically written for <Interger,Object> such hashmap in Android, designed to improve efficiency, with the core of binary lookup function (binarysearch). In Android, when we need to define
1 |
HashMap<Integer, E> hashMap = new HashMap<Integer, E>(); |
, we can use the following methods to achieve better performance.
1 |
SparseArray<E> sparseArray = new SparseArray<E>(); |
Android app performance optimization using Sparsearray instead of HashMap