Android開發中高效的數據結構用SparseArray代替HashMap
android開發中,在java2ee或者android中常用的數據結構有Map,List,Set,但android作為移動平臺,有些api(很多都是效率問題)顯然不夠理想,本著造更好輪子的精神,android團隊編寫了自己的api用來代替java api
1、SimpleArrayMap<K,V>與ArrayMap<K,V>
實質上ArrayMap繼承自SimpleArrayMap,主要是為了實現像HashMap一樣的api方法,讓習慣使用HashMap的開發者感覺不到差異,本質上是SimpleArrayMap+Map的再封裝。
一般來說使用這2個類主要來代替HashMap,因為他們比HashMap更加高效,對內存也進行了優化。
2、SparseArray<T>與SparseArrayCompat<T>和LongSparseArray<T>
這3個類中,前2個基本上是同一類,只不過第二個類有removeAt方法,第三個是Long類型的。
這3個類也是用來代替HashMap,只不過他們的鍵(key)的類型是整型Integer或者Long類型,在實際開發中,如月份縮寫的映射,或者進行文件緩存映射,viewHolder都特別適用
3、AtomicFile
AtomicFile首先不是用來代替File的,而是作為File的輔助類從在, AtomicFile的作用是實現事務性原子操作,即文件讀寫必須完整,適合多線程中的文件讀寫操作。
用來實現多線程中的文件讀寫的安全操作
----
#####用SparseArray代替HashMap
SparseArray是android提供的一個工具類,它可以用來替代hashmap進行對象的存儲,其內部實現了一個矩陣壓縮算法,很適合存儲稀疏矩陣的。
PS:support包中還提供了兼容的類SparseArrayCompat,基本和SparseArray是同一個類,只不過第二個類有removeAt方法
針對源碼的詳細分析:[http://stormzhang.com/android/2013/08/01/android-use-sparsearray-for-performance-optimization/](http://stormzhang.com/android/2013/08/01/android-use-sparsearray-for-performance-optimization/
"http://stormzhang.com/android/2013/08/01/android-use-sparsearray-for-performance-optimization/")
一、和Hashmap的對比
既然android推薦用這個東西,自然有用它的道理。其內部實現了壓縮算法,可以進行矩陣壓縮,大大減少了存儲空間,節約內存。此外它的查找算法是二分法,提高了查找的效率。
替換原則:
1>
如果用到了: HashMap<Integer, E> hashMap = new HashMap<Integer, E>();
可以替換為:SparseArray<E> sparseArray = new SparseArray<E>();
2>
如果用到了:HashMap<Integer, Boolean> hashMap = new HashMap<Integer, Boolean>
可以替換為:SparseBooleanArray array = new SparseBooleanArray();
3>
如果用到了:HashMap<Integer, Integer> hashMap = new HashMap<Integer, Integer>
可以替換為:SparseIntArray array = new SparseIntArray();
二、用法
既然是鍵值對那么就有增刪改查,但要記得先初始化:
Button btn = null; // 測試view,無意義
Button btn02 = null; // 測試view,表示新增的對象
final int KEY = 1;
/*
* SparseArray指的是稀疏數組(Sparse
* array),所謂稀疏數組就是數組中大部分的內容值都未被使用(或都為零),在數組中僅有少部分的空間使用
* 。因此造成內存空間的浪費,為了節省內存空間,并且不影響數組中原有的內容值,我們可以采用一種壓縮的方式來表示稀疏數組的內容。
*/
SparseArray<View> array = new SparseArray<View>();
2.1 增加數據
/* 增加數據 */
//public void put(int key, E value) {}
array.put(KEY, btn);
//public void append(int key, E value){}
array.append(KEY, btn);
2.2 修改數據
/* 修改數據 */
//在put數據之前,會先查找要put的數據是否已經存在,如果存在就是修改,不存在就添加。
//public void put(int key, E value)
array.put(KEY, btn);
//public void setValueAt(int index, E value)
array.setValueAt(KEY, btn02);
2.3 查找數據
/* 查找數據 */
//public E get(int key)
array.get(KEY);
//public E get(int key, E valueIfKeyNotFound)
//其中get(int key)也只是調用了 get(int key,E valueIfKeyNotFound),最后一個從傳參的變量名就能看出,傳入的是找不到的時候返回的值.get(int key)當找不到的時候,默認返回null。
array.get(KEY, btn); // 如果這個key找不到value,那么就返回第二個參數。和default value一樣
2.4 通過位置,查找鍵的值
// 查看第幾個位置的鍵:
//public int keyAt(int index)
array.keyAt(1); // 如果找不到就返回-1
2.5 通過位置,查找值
// 查看第幾個位置的值:
//public E valueAt(int index)
array.valueAt(1);
// 查看值所在位置,沒有的話返回-1:
//public int indexOfValue(E value)
array.indexOfValue(btn);
三、測試代碼
package com.kale.pictest;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.view.View;
import android.widget.Button;
/**
* @author:
* @description :
* @web : http://stormzhang.com/android/2013/08/01/android-use-sparsearray-for-performance-optimization/
* @date :2015年1月19日
*/
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
Log.d("TAG", "Max memory is " + maxMemory + "KB");
Button btn = null; // 測試view,無意義
Button btn02 = null; // 測試view,表示新增的對象
final int KEY = 1;
/*
* SparseArray指的是稀疏數組(Sparse
* array),所謂稀疏數組就是數組中大部分的內容值都未被使用(或都為零),在數組中僅有少部分的空間使用
* 。因此造成內存空間的浪費,為了節省內存空間,并且不影響數組中原有的內容值,我們可以采用一種壓縮的方式來表示稀疏數組的內容。
*/
SparseArray<View> array = new SparseArray<View>();
/* 增加數據 */
//public void put(int key, E value) {}
array.put(KEY, btn);
//public void append(int key, E value){}
array.append(KEY, btn);
/* 修改數據 */
//在put數據之前,會先查找要put的數據是否已經存在,如果存在就是修改,不存在就添加。
//public void put(int key, E value)
array.put(KEY, btn);
//public void setValueAt(int index, E value)
array.setValueAt(KEY, btn02);
/* 查找數據 */
//public E get(int key)
array.get(KEY);
//public E get(int key, E valueIfKeyNotFound)
//其中get(int key)也只是調用了 get(int key,E valueIfKeyNotFound),最后一個從傳參的變量名就能看出,傳入的是找不到的時候返回的值.get(int key)當找不到的時候,默認返回null。
array.get(KEY, btn); // 如果這個key找不到value,那么就返回第二個參數。和default value一樣
// 查看第幾個位置的鍵:
//public int keyAt(int index)
array.keyAt(1); // 如果找不到就返回-1
// 查看第幾個位置的值:
//public E valueAt(int index)
array.valueAt(1);
// 查看值所在位置,沒有的話返回-1:
//public int indexOfValue(E value)
array.indexOfValue(btn);
SparseBooleanArray d;
}
}
測試代碼四:
public class FragmentPagerItemAdapter extends FragmentPagerAdapter {
private final FragmentPagerItems mPages;
private final SparseArrayCompat<WeakReference<Fragment>> mHolder;
public FragmentPagerItemAdapter(FragmentManager fm, FragmentPagerItems pages) {
super(fm);
mPages = pages;
mHolder = new SparseArrayCompat<>(pages.size());
}
@Override
public int getCount() {
return mPages.size();
}
@Override
public Fragment getItem(int position) {
return getPagerItem(position).instantiate(mPages.getContext(), position);
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
Object item = super.instantiateItem(container, position);
if (item instanceof Fragment) {
mHolder.put(position, new WeakReference<Fragment>((Fragment) item));
}
return item;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
mHolder.remove(position);
super.destroyItem(container, position, object);
}
@Override
public CharSequence getPageTitle(int position) {
return getPagerItem(position).getTitle();
}
@Override
public float getPageWidth(int position) {
return super.getPageWidth(position);
}
public Fragment getPage(int position) {
final WeakReference<Fragment> weakRefItem = mHolder.get(position);
return (weakRefItem != null) ? weakRefItem.get() : null;
}
protected FragmentPagerItem getPagerItem(int position) {
return mPages.get(position);
}
}
本文由用戶 likeo 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!