SparseArray详解

来源:互联网 发布:div into python 编辑:程序博客网 时间:2024/05/29 13:24
  1. SparseArray用于映射integers到object。但不像普通数组那样,sparseArray的元素间没有无用元素。 在映射integers到object的过程中,SparseArray由于采用避免自动装箱的keys和它的数据结构不依赖额外的对象来存储映射关系的实现,因此它比hashMap的内存使用更高效一些。 
  2. SparseArray在查找keys的过程中采用了二分查找, 这种实现不适合数据量大的情况。由于查找时要用到二分查找,添加删除时涉及到数组其他元素的挪动,
  3. 因此通常SparseArray会比hashMap慢。当处理上百的数据量,这种性能差异不是特别明显,性能差异不超过50%。 
  4. 为了优化性能,SparseArray针对remove case作了优化,remove时它不是立即挤压数组空间,而是标记为delete。 这个被标记的元素要么被重复利用,要
  5. 么在多次remove之后通过一次gc操作中被挤压出去。gc需要在下列情况之前被执行:数组要扩容;get map size;get values;
  6. 核心的put代码如下:

      1.     /** 
      2.      * Adds a mapping from the specified key to the specified value, 
      3.      * replacing the previous mapping from the specified key if there 
      4.      * was one. 
      5.      */  
      6.     public void put(int key, E value) {  
      7.         //先二分查找,确定插入位置,保证了key数组的有序性  
      8.         int i = ContainerHelpers.binarySearch(mKeys, mSize, key);  
      9.   
      10.         if (i >= 0) {  
      11.             //找到了,直接替换  
      12.             mValues[i] = value;  
      13.         } else {  
      14.             //一点小技巧,跟二分查找的返回值有关  
      15.             //没找到的情况下i的意义是 i = -insertPoint -1,比如i=-2,则insertPoint=1  
      16.             //而-2在内存中存的是补码,对他取反刚好得insertPoint,跟上面计算结果一样,但位操作更高效  
      17.             i = ~i;  
      18.   
      19.             //若i在size范围内,且刚好对应位置标记为delete了,直接放入  
      20.             if (i < mSize && mValues[i] == DELETED) {  
      21.                 mKeys[i] = key;  
      22.                 mValues[i] = value;  
      23.                 return;  
      24.             }  
      25.   
      26.             //若前面if不成立,即i超出了size范围,或者对应的位置的元素是有效的  
      27.             if (mGarbage && mSize >= mKeys.length) {  
      28.                 //压缩空间  
      29.                 gc();  
      30.   
      31.                 //重新查找插入点  
      32.                 // Search again because indices may have changed.  
      33.                 i = ~ContainerHelpers.binarySearch(mKeys, mSize, key);  
      34.             }  
      35.   
      36.             //插入,若空间不够则会重新分配数组  
      37.             mKeys = GrowingArrayUtils.insert(mKeys, mSize, i, key);  
      38.             mValues = GrowingArrayUtils.insert(mValues, mSize, i, value);  
      39.             mSize++;  
      40.         }  
      41.     } 

     
0 0
原创粉丝点击