簡單梳理Android常用基本容器類原理

Android-Java:常用基本容器學習總結

1.常用容器的總體框架

在這裏插入圖片描述

2.常用容器類的重點

1. ArrayList

https://www.cnblogs.com/skywang12345/p/3308556.html

1.1 存儲結構:
在這裏插入圖片描述
value值存在elementData這個Object類型的數組中,默認容量是10。
1.2 容器特點:

  1. ArrayList 是一個數組隊列,相當於 動態數組。與Java中的數組相比,它的容量能動態增長。
  2. ArrayList 實現java.io.Serializable接口,這意味着ArrayList支持序列化,能通過序列化去傳輸.
  3. ArrayList中的操作不是線程安全的!所以,建議在單線程中才使用ArrayList.

1.3 注意事項:
5. 遍歷ArrayList時,使用隨機訪問(即,通過索引序號訪問)效率最高,而使用迭代器的效率最低
6. ArrayList中的操作不是線程安全的!所以,建議在單線程中才使用ArrayList.

2. Vector

Vector 是矢量隊列,繼承於AbstractList,實現了List, RandomAccess, Cloneable這些接口。
https://www.cnblogs.com/skywang12345/p/3308833.html
2.1 存儲結構:
在這裏插入圖片描述
value值存在elementData這個Object類型的數組中,默認容量是10。

2.2 容器特點:

  1. Vector中的操作是線程安全的,add(),remove(),clear()等操作均加上了synchronized保護;
    在這裏插入圖片描述

3. Stack

Stack是繼承Vector來實現,基於Vector的addElement和removeElement來實現push,pop,peek操作,因此Stack也是通過數組實現的,而非鏈表。
3.1 存儲結構:
實質上還是用的Vector的數組實現:
在這裏插入圖片描述

3.2 容器特點:

  1. Stack實際上也是通過數組去實現的。
    執行push時(即,將元素推入棧中),是通過將元素追加的數組的末尾中。
    執行peek時(即,取出棧頂元素,不執行刪除),是返回數組末尾的元素。
    執行pop時(即,取出棧頂元素,並將該元素從棧中刪除),是取出數組末尾的元素,然後將該元素從數組中刪除。
  2. Stack繼承於Vector,意味着Vector擁有的屬性和功能,Stack都擁有。

4. HashMap

http://androidxref.com/9.0.0_r3/xref/libcore/ojluni/src/main/java/java/util/HashMap.java
4.1 存儲結構:
JDK1.8 鏈表結構優化爲數組+紅黑樹形式:
在這裏插入圖片描述

JDK1.8 之前數據+鏈表實現:
在這裏插入圖片描述
數組是HashMap的主體,鏈表,紅黑樹則是主要爲了解決哈希衝突而存在的,如果定位到的數組位置不含鏈表或紅黑樹,那麼對於查找,添加等操作很快,僅需一次尋址即可;

如果定位到的數組包含鏈表,對於添加操作,其時間複雜度爲O(n),首先遍歷鏈表,存在即覆蓋,否則新增;對於查找操作來講,仍需遍歷鏈表,然後通過key對象的equals方法逐一比對查找。

所以,性能考慮,HashMap中的鏈表出現越少,性能纔會越好。

4.2 容器特點:

  1. HashMap線程不安全;
  2. HashMap可以接受爲null的鍵值(key)和值(value)

5. HashTable

HashTable和Hashmap類似,有個HashTableEntry 類型的數組成員變量table,管理着鍵值對。
在這裏插入圖片描述
Hashtable是synchronized,這意味着Hashtable是線程安全的

但是HashTable已經被淘汰了,如果不需要線程安全,那麼使用HashMap,如果需要線程安全,那麼使用ConcurrentHashMap。
5.1 HashTable方法API:
在這裏插入圖片描述

5.2 容器特點:

  1. Hashtable 的函數都是同步的,這意味着它是線程安全的。
  2. 它的key、value都不可以爲null。
  3. Hashtable中的映射不是有序的。
  4. 該類型已經提示被淘汰,需要線程安全的話可以使用ConcurrentHashMap

6. HashSet

  1. HashSet是一個集合,集合中不允許出現重複元素。
  2. HashSet是基於HashMap實現,HashSet中有一個HashMap的成員變量map,HashSet的Value 值會被以鍵值對<Value,PRESENT>加入到map中,由於HashMap不可以有重複的key,因而實現了set的去重。

6.1 注意事項:

  1. HashSet實現了Set接口,它不允許集合中出現重複元素。當我們提到HashSet時,第一件事就是在將對象存儲在HashSet之前,要確保重寫hashCode()方法和equals()方法,這樣才能比較對象的值是否相等,確保集合中沒有儲存相同的對象。
    案例:https://www.cnblogs.com/dongying/p/4024519.html

7. ConcurrentHashMap

原理:http://www.cnblogs.com/chengxiao/p/6842045.html

7.1 存儲結構:
在這裏插入圖片描述
Segmemt:
每個綠色方塊是ConcurrentHashMap的一個Node:
在這裏插入圖片描述

7.2 容器特點:
1.ConcurrentHashMap是線程安全的;
1.ConcurrentHashMap不同於HashMap,它既不允許key值爲null,也不允許value值爲null;
2.HashTable容器的get方法是需要加鎖的,而ConcurrentHashMap的get操作是不加鎖的,原因是它的get方法裏將要使用的共享變量都定義成volatile;
3.在ConcurrentHashMap中,每個hash區間使用的鎖是ReentrantLock;

Android中獨有的:

8. SparseArray

8.1 存儲結構:
在這裏插入圖片描述
8.2 容器特點

  1. SparseArray在存儲和讀取數據時候,使用的是二分查找法;
  2. 滿足下面兩個條件我們能夠使用SparseArray取代HashMap:
    a.數據量不大,最好在千級以內;
    b.key必須爲int類型,這中情況下的HashMap能夠用SparseArray取代;
  3. SparseArray被稱爲稀疏數組,原因是數組中可能並不是連續存儲着value,remove方法並沒有去直接刪掉元素,而是將這個key指向了DELETED,這時候value失去了引用,如果沒有其它的引用,會在下一次系統內存回收的時候被幹掉,或者該key被複用指向新的值,是一個優化;
  4. SparseArray不需要開闢內存空間來額外存儲外部映射,從而節省內存,key爲int的時候才能使用,注意是int而不是Integer,這也是sparseArray效率提升的一個點,去掉了Hashmap的裝箱的操作。

9. ArrayMap

https://www.jianshu.com/p/1fb660978b14
9.1數據結構:
在這裏插入圖片描述

  1. 數據變量含義:
    (1)mHashes,用於保存key對應的hashCode;
    (2)mArray,用於保存鍵值對(key,value),其結構爲[key1,value1,key2,value2,key3,value3,…];
    (3)mBaseCache,緩存,如果ArrayMap的數據量從4,增加到8,用該數組保存之前使用的mHashes和mArray,這樣如果數據量再變回4的時候,可以再次使用之前的數組,不需要再次申請空間,這樣節省了一定的時間;
    (4)mTwiceBaseCache,與mBaseCache對應,不過觸發的條件是數據量從8增長到12;
  2. allocArrays()
  3. 適用場景:
    a. 數據量不大
    b.空間比時間重要
    c.需要使用Map在Android平臺,相對來說,內存容量更寶貴。而且數據量不大。所以當需要使用key是Object類型的Map時,可以考慮使用ArrayMap來替換HashMap
  4. 中佔據時間複雜度最多的屬於第一步:確定key的hashCode在mHahses中的索引值。而這一步對mHashes查找使用的是二分查找,即Binary Search。所以ArrayMap的查詢時間複雜度爲 ‎O(log n);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章