Android开发中高效的数据结构用SparseArray代替HashMap

####Android开发中高效的数据结构

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);

    }

    }

    原文作者:fancylovejava
    原文地址: https://blog.csdn.net/fancylovejava/article/details/45148325
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞