Map和SparseArray的PK。
2017-04-04 本文已影响0人
远行的猿
Map
Map这是Java语言自带的一种容器
使用起来比较简单,很多数据结构中用的相当频繁,
众所周知,Map是一个接口。我们看下关于
A、Map的集合实现,键值对的一一对象存储关系。
** B、Map集合中不能包含相同的key(键值)--此处是通过Key的散列码区分。**
Map相关的方法:
clear():清除Map集合的所有数据。
containKey(Object var1):是否包含键。返回的数boolean数据。
containValue(Object var1):是否包含某个值。
isEmpty():是否为空。
put(K var1, V var2):添加键值对。
putAll(Map<? extends K, ? extends V> var1);添加一个Map集合(但是两个集合的键值对的对象是同类的)。
remove(Object var1):删除某个键值对。参数是key值。
size():Map集合的大小。
Map集合的遍历方式:
1、迭代器遍历
Iterator iterator = map.entrySet().iterator();
while ( iterator.hasNext() ) {
Map.Entry entry = (Map.Entry) iterator.next();
Object valueObject = entry.getValue();
Object keyObject = entry.getKey();
}![image](http://note.youdao.com/favicon.ico)
2、foreach遍历
for (Map.Entry entry : map.entrySet()) {
Object keyObject = entry.getKey();
Object valueObject = entry.getValue();
}
3、单独取值遍历
Map<Object, Object> map = new HashMap();
for (Object object : map.keySet()) {
//获取到的是Key.
}
for(Object object : map.values()){
//获取的是values.
}
Map实现类的相关介绍
(1)HashMap是一个最常用的Map,它根据键的hashCode值存储数据,根据键可以直接获取它的值,具有很快的访问速度。
A、HashMap最多只允许一条记录的键为null,允许多条记录的值为null。
B、HashMap不支持线程的同步,即任一时刻可以有多个线程同时写HashMap,可能会导致数据的不一致。
C、如果需要同步,可以用Collections.synchronizedMap(HashMap map)方法使HashMap具有同步的能力。
(2)Hashtable与HashMap类似,不同的是:
A、它不允许记录的键或者值为空;
B、它支持线程的同步,即任一时刻只有一个线程能写Hashtable,然而,这也导致了Hashtable在写入时会比较慢。
(3)LinkedHashMap保存了记录的插入顺序,在用Iteraor遍历LinkedHashMap时,先得到的记录肯定是先插入的。 在遍历的时候会比HashMa慢。
(4)TreeMap能够把它保存的记录根据键排序,默认是按升序排序,也可以指定排序的比较器。当用Iteraor遍历TreeMap时,得到的记录是排过的。
SparseArray
SparseArray是Android里了替代hashMap这样的数据结构的产生的 目的是为了提高内存的使用效率。(SparseArray采用的是折半查找)
SparseArray相关特点
在google的官方文档中也提及到了内存效率高些。主要是有以下两点吧(与HashMap相比)
A、不需要进行对象转化。(HashMap的键值都是对象。SparseArray是常见的数据类型)。
B、数据结构的差异,与hashMap的散列码以及哈希值不一样的在于,底层的是用过一个数组实现的。通过折半对数组进行一系列的操作,所以其实在查询上可能还会比HashMap慢,但是在添加和删除操作中,会提高百分之50的内存效率。
C、大量的数据我们相对SparseArray会优先选择HashMap,如果数据在几百个这个数目, 那么选择它们任意一个去实现区别不大,如果数量较少,就选择SparseArray去实现。
SparseArray相关的方法
每个数据结构,无非就是增删改查
- clone() 克隆一个与当前SparseArray不是同一个存储地址的SparseAarry相当于 new 一个当前的SparseArray.
- 增
-
append(int key, E value) 添加数据的时候,相当于StringBuilder的添加方法,在最后一位添加。
-
put(int key, E value)
这个就和HashMap差不多吧,如果当前有key的话就替代value之前已经有的。
其实我后来研究了一下,这两个方法本质是一样的 没有什么区别。都是一样的功能如果只是单纯看文档说明就是上面我说的意思。我们来看看源码吧
-
/**
* Puts a key/value pair into the array, optimizing for the case where
* the key is greater than all existing keys in the array.
*/
public void append(int key, E value) {
if (mSize != 0 && key <= mKeys[mSize - 1]) {
put(key, value);
return;
}
if (mGarbage && mSize >= mKeys.length) {
gc();
}
mKeys = GrowingArrayUtils.append(mKeys, mSize, key);
mValues = GrowingArrayUtils.append(mValues, mSize, value);
mSize++;
}
append方法还是会调put方法的。
-
删
- delete(int key)
-
remove(int key)
上面的方法都是通过删除的方式,其实是一样的。 - removeAt(int index) 这就是通过索引值删除这数据。
- clear() 清空所有的Key-Values的数据.
remove()源码如下:
/**
* Alias for {@link #delete(int)}.
*/
public void remove(int key) {
delete(key);
}
-
改
- **setValueAt(int index, E value) ** 修改对应该的index去修改对应的Value
- 还有就是put以及append方法了。这也是修改数据的方法。
-
查
- indexOfKey(int key) 和 indexOfValue(E value) 查找索引值(角标)。
- keyAt(int index) 和 valueAt(int index)就是通过索引值查找对于的key和Value.
-
gc()
- 这是SparseArray自己构建的回收机制。
SparseArray的遍历
for (int x = 0; x < sparseArray.size();x ++){
int key = sparseArray.keyAt(x);
String values = sparseArray.valueAt(x);
}
可以只取key或者Values. 看个人需求。
以上有什么有问题的地方,多多担待