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();
}
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. 看個人需求。
以上有什么有問題的地方,多多擔待