Usually when we use Key-value to store data, we can easily hit the HashMap code, when the amount of data is small, but also, when the number of times, if it is a PC, but also plausible, but if the use of mobile devices such as mobile device, this is to be cautious. Because the memory of the phone is very valuable, unlike the PC as reckless use, improper memory use can easily cause oom problems. The Android development team also found a substitute for HashMap arraymap.
Official Arraymap also stated: It is not a data structure to adapt to big data, compared to the traditional HashMap speed is slower, because the lookup method is a dichotomy, and when you delete or add data, the space is re-adjusted, when using a large amount of data, the efficiency is not obvious, less than 50%.
So Arraymap was sacrificed time to swap space. When you write a mobile app, using Arraymap in a timely manner can bring a significant boost to memory usage.
What is the difference between HashMap and Arraymap, the personal summary has the following aspects:
1, different storage methods.
HashMap has a hashmapentry<k, v>[] object, each key-value pair is stored in this object, and when you add a key-value pair using the Put method, a new Hashmapentry object
@Override public V put (K key, V value) {if (key = = null) {return Putvaluefornullkey (value); } int hash = Secondaryhash (key); Hashmapentry<k, v>[] tab = table; int index = hash & (tab.length-1);//First look for the corresponding key value, if any, overwrite value, and return the value before overwriting: OldValue for (hashmapentry<k, V> e = Tab[index]; E! = null; E = e.next) {if (E.hash = = Hash && key.equals (E.key)) {premodify (e); V oldValue = E.value; E.value = value; return oldValue; }}//No entry for (Non-null) key is present; Create one modcount++; if (size++ > Threshold) {//expansion, double tab = doublecapacity (); Index = hash & (tab.length-1); } addnewentry (key, value, hash, index); return null; }//Create object store key value pair void Addnewentry (K key, V value, int hash, int index) {Table[index] = new Hashmapentry<k, V> (key, value, hash, Table[index]); }
There is no entry this thing in Arraymap's storage, he is maintained by two arrays
Int[] mhashes; Object[] Marray;
Mhashes array is saved in the Hashcode value of each item, Marray is a key-value pair, each two elements represent a key value pair, before saving key, after the save value, we look at the results of the following code
Arraymap = new hashmap<string, string> (), A.put ("A", "A_value"), A.put ("B", "B_value");
After executing the above code, the storage in Arraymap is like this
Is it clear to see Arraymap's storage, which is stored in the put code as follows
Mhashes[index] = hash; MARRAY[INDEX<<1] = key; marray[(index<<1) +1] = value;
2. When adding data, the processing is different when expanding
Let's take a look at HashMap
if (size++ > Threshold) { tab = doublecapacity (); Index = hash & (tab.length-1); }
doublecapacityTo double the expansion, it's in the code with this sentence
Hashmapentry<k, v>[] newtable = maketable (newcapacity);
Finally, the newtable will be returned as a new object after the expansion, so what does maketable do, as follows:
Private hashmapentry<k, v>[] maketable (int newcapacity) { @SuppressWarnings ("unchecked") hashmapentry<k , v>[] newtable = (hashmapentry<k, v>[]) new hashmapentry[newcapacity]; Table = newtable; Threshold = (newcapacity >> 1) + (newcapacity >> 2); 3/4 capacity return newtable; }
We clearly see that the new operation is done here and recreating the object is expensive.
So arraymap, look at it.
If the capacity is insufficient if (msize >= mhashes.length) { final int n = msize >= (base_size*2)? (Msize+ (msize>>1)) : (msize >= 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; Allocation array allocarrays (n); if (Mhashes.length > 0) { if (DEBUG) log.d (TAG, "Put:copy 0-" + msize + "to 0"); Pay special attention to this, which is copy, not new, efficiency boost system.arraycopy (ohashes, 0, mhashes, 0, ohashes.length); System.arraycopy (Oarray, 0, Marray, 0, oarray.length); } Frees the unused space, shrinks the array freearrays (ohashes, Oarray, msize); }
Arraymap uses copy data, so the efficiency is relatively high.
3, Arraymap provides the function of array contraction, after clear or remove, will re-shrink the array, whether the space
4, Arraymap using binary method to find (see Android.support.v4.util.ContainerHelpers in the BinarySearch method)
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Android Memory Optimizer: Arraymap