Android中利用SparseArray来实现映射效果

Android中利用SparseArray来实现映射效果

                                                                                                                      2013-08-04        16:35:56

  映射是在项目开发中常见的知识,用来将键值对进行绑定,一个键对应一个值,所以提供了键就能找到相应的值。我们在java中一般是用HashMap和TreeMap来实现映射的,这两个类都实现了Map接口。

  而SparseArray是Android提供的一个类,也是用来实现映射的。SparseArray指的是稀疏数组(Sparse array),所谓稀疏数组就是数组中大部分的内容值都未被使用(或都为零),在数组中仅有少部分的空间使用。因此造成内存空间的浪费,为了节省内存空间,并且不影响数组中原有的内容值,我们可以采用一种压缩的方式来表示稀疏数组的内容。

假设有一个9*7的数组,其内容如下:

 

 

在此数组中,共有63个空间,但却只使用了5个元素,造成58个元素空间的浪费。以下我们就使用稀疏数组重新来定义这个数组:

 

 

其中在稀疏数组中第一部分所记录的是原数组的列数和行数以及元素使用的个数、第二部分所记录的是原数组中元素的位置和内容。经过压缩之后,原来需要声明大小为63的数组,而使用压缩后,只需要声明大小为6*3的数组,仅需18个存储空间。

  由此可见,利用SparseArray实现映射具有更高的效率。所以在Android开发过程中推荐使用SparseArray来实现映射。下面,通过一个简单的demo来实现SparseArray的映射。

  本程序是用来实现将从服务端获得的“部门名字”和“部门ID”进行映射的,当点击相应“部门名字”的Item后返回”部门ID“给服务端。先看看本程序的结构框:

   本程序中有3个类,其中MyData是用来封装相应属性和对应操作的,代码如下:

 

 1 public class MyData {
 2 
 3     public String name;//部门名字
 4     public int id;//部门id
 5     /**
 6      *还 需要什么成员数据自己加
 7      * */
 8     
 9     public void setName(String name)
10     {
11         this.name = name;
12     }
13     
14     public void setId(int id)
15     {
16         this.id = id;
17     }
18     
19     public String getName()
20     {
21         return this.name;
22     }
23     
24     public int getId()
25     {
26         return this.id;
27     }
28     
29     public static SparseArray<MyData> mdatalist = new SparseArray<MyData>();
30     
31     /**
32      * 添加数据
33      * @param data
34      */
35     public static void add(MyData data)
36     {
37         mdatalist.put(data.id, data);
38     }
39     
40     /**
41      * 根据Key得到一个数据
42      * */
43     public static MyData getDataAtKey(int key)
44     {
45         return mdatalist.get(key);
46     }
47     
48     /**
49      * 根据集合的顺序位置index得到一个数据
50      * */
51     public static MyData getDataAtIndex(int index)
52     {
53         return mdatalist.valueAt(index);
54     }
55     
56     public static SparseArray<MyData> getList()
57     {
58         return mdatalist;
59     }
60     
61 }

  MyAdapter是用来给没一个Item设置适配器的,继承了BaseAdapter,代码如下:

 1 public class MyAdapter extends BaseAdapter {
 2 
 3     private SparseArray<MyData> list;
 4     private MyData data;
 5     private Context context = null;
 6     
 7     public MyAdapter(SparseArray<MyData> list,Context mcontext)
 8     {
 9         context = mcontext;
10         this.list = list;
11     }
12     
13     @Override
14     public int getCount() {
15         // TODO Auto-generated method stub
16         return list.size();
17     }
18 
19     @Override
20     public Object getItem(int index) {
21         // TODO Auto-generated method stub
22         return list.valueAt(index);
23     }
24 
25     @Override
26     public long getItemId(int index) {
27         // TODO Auto-generated method stub
28         return list.valueAt(index).getId();
29     }
30 
31     @Override
32     public View getView(int position, View convertView, ViewGroup parent) {
33         ViewHandler mhandler;
34         data = list.valueAt(position);
35         if(convertView == null)
36         {
37             convertView = ((Activity)context).getLayoutInflater().inflate(R.layout.list_item, null);
38             mhandler = new ViewHandler();
39             mhandler.name = (TextView)convertView.findViewById(R.id.mtextview_name);
40             mhandler.id = (TextView)convertView.findViewById(R.id.mtextview_id);
41             convertView.setTag(mhandler);
42         }else{
43             mhandler = (ViewHandler)convertView.getTag();
44         }
45         if(data != null)
46         {
47             mhandler.name.setText(""+data.getName());
48             mhandler.id.setText("部门id是:"+data.getId());
49         }
50         return convertView;
51     }
52     
53     
54     class ViewHandler{
55         TextView name;
56         TextView id;
57     }
58 
59 }

  MainActivity是用来加载数据和为Item设置监听的,代码如下:

 1 public class MainActivity extends Activity {
 2 
 3     private ListView mlist;
 4     private MyAdapter adapter;
 5     
 6     @Override
 7     protected void onCreate(Bundle savedInstanceState) {
 8         super.onCreate(savedInstanceState);
 9         setContentView(R.layout.activity_main);
10         try {
11             setData();
12             mlist = (ListView)findViewById(R.id.mylist);
13             adapter = new MyAdapter(MyData.getList(), this);
14             mlist.setAdapter(adapter);
15             
16             mlist.setOnItemClickListener( new OnItemClickListener() {
17                 @Override
18                 public void onItemClick(AdapterView<?> arg0, View view, int position,
19                         long id) {
20                     // TODO Auto-generated method stub
21                     MyData mdata = (MyData)arg0.getItemAtPosition(position);//根据点击项获取数据(获取这个数据,你就可以得到你要的所有信息了,比如id->mdata.getId())
22                     Toast.makeText(MainActivity.this, "点击得到的数据id是:"+mdata.getId(), Toast.LENGTH_SHORT).show();
23 
24                 }
25             });
26         } catch (Exception e) {
27             e.printStackTrace();
28         }
29     }
30     
31     /**
32      * 模拟收到数据
33      * */
34     private void setData()
35     {
36         MyData data;
37         for(int i=0;i<20;++i)
38         {
39             data = new MyData();
40             data.setId(i);
41             data.setName("部门测试数据"+i);
42             MyData.add(data);
43         }
44     }
45 
46     @Override
47     public boolean onCreateOptionsMenu(Menu menu) {
48         // Inflate the menu; this adds items to the action bar if it is present.
49         getMenuInflater().inflate(R.menu.activity_main, menu);
50         return true;
51     }
52 
53 }

   通过以上的代码就可以实现利用SparseArray来实现”部门名称“和”部门ID“映射的效果了。


 

 

posted @ 2013-08-04 16:45  蠢驴  阅读(260)  评论(0)    收藏  举报