Java數據結構之Map學習總結

前言:

    前面學習總結了List的使用及效率對比,今天總結學習一下鍵值映射關係Map,順便學習一下Android中使用Map須要注意哪些,以及谷歌官方針對Android對Map作了哪些優化。編程

先了解下Map

   Map 是一種把鍵對象和值對象映射的集合,它的每個元素都包含一對鍵對象和值對象。 Map沒有繼承於Collection接口 從Map集合中檢索元素時,只要給出鍵對象,就會返回對應的值對象。 數組

Map是一個接口,實例化Map能夠採用下面的方式:安全

  • HashMap //Map基於散列表的實現。插入和查詢「鍵值對」的開銷是固定的。能夠經過構造器設置容量capacity和負載因子load factor,以調整容器的性能。 
  • LinkedHashMap  //相似於HashMap,可是迭代遍歷它時,取得「鍵值對」的順序是其插入次序,或者是最近最少使用(LRU)的次序。只比HashMap慢一點。而在迭代訪問時發而更快,由於它使用鏈表維護內部次序。 
  • TreeMap //底層是二叉樹數據結構,線程不一樣步,可用於給Map集合中的鍵進行排序。
  • HashTable //HashMap是Hashtable的輕量級實現,非線程安全的實現他們都實現了map接口,主要區別是HashMap鍵值能夠爲空null,效率能夠高於Hashtable。
  • ConcurrentHashMap //ConcurrentHashMap一般只被看作併發效率更高的Map,用來替換其餘線程安全的Map容器,好比Hashtable和Collections.synchronizedMap。
  • WeakHashMap //弱鍵(weak key)Map,Map中使用的對象也被容許釋放: 這是爲解決特殊問題設計的。若是沒有map以外的引用指向某個「鍵」,則此「鍵」能夠被垃圾收集器回收。
  • IdentifyHashMap //使用==代替equals()對「鍵」做比較的hash map
  • ArrayMap //ArrayMap是一個<key,value>映射的數據結構,它設計上更多的是考慮內存的優化,內部是使用兩個數組進行數據存儲,一個數組記錄key的hash值,另一個數組記錄Value值,它和SparseArray同樣,也會對key使用二分法進行從小到大排序,在添加、刪除、查找數據的時候都是先使用二分查找法獲得相應的index,而後經過index來進行添加、查找、刪除等操做,因此,應用場景和SparseArray的同樣,若是在數據量比較大的狀況下,那麼它的性能將退化至少50%。
  • SparseArray //SparseArray比HashMap更省內存,在某些條件下性能更好,主要是由於它避免了對key的自動裝箱(int轉爲Integer類型),它內部則是經過兩個數組來進行數據存儲的,一個存儲key,另一個存儲value,爲了優化性能,它內部對數據還採起了壓縮的方式來表示稀疏數組的數據,從而節約內存空間。

Map的基本操做:數據結構

  • Object put(Object key, Object value): 向集合中加入元素   
  • Object remove(Object key): 刪除與KEY相關的元素   
  • void putAll(Map t):  未來自特定映像的全部元素添加給該映像   
  • void clear():從映像中刪除全部映射   

Map使用

  這裏以最經常使用的HashMap爲例併發

 添加數據性能

   Map<Integer, String> hashMap = new HashMap<>();
   for (int i = 0; i < maxCount; i++) {
      hashMap.put(i, String.valueOf(i));
   }

遍歷entrySet方式學習

 long start = System.currentTimeMillis();
 for (Map.Entry<Integer, String> entry : hashMap.entrySet()) {
        Integer key=entry.getKey();
        String  value=entry.getValue();
        Log.i(TAG, "key: " + key +"value: "+value);
     }

    long end = System.currentTimeMillis();
    Log.e(TAG, "for-each方式 cost time : " + (end - start));

entrySet迭代器遍歷方式優化

long start1 = System.currentTimeMillis();
Iterator<Map.Entry<Integer, String>> entries = hashMap.entrySet().iterator();

while (entries.hasNext()) {
    Map.Entry<Integer, String> entry = entries.next();
    Integer key=entry.getKey();
    String  value=entry.getValue();
    Log.i(TAG, "key: " + key +"value: "+value);
   }

long end1 = System.currentTimeMillis();
Log.e(TAG, "entrySet iterator迭代器 cost time : " + (end1 - start1));

鍵找值遍歷spa

 long end1 = System.currentTimeMillis();
 Log.e(TAG, "iterator迭代器 cost time : " + (end1 - start1));

 long start2 = System.currentTimeMillis();
 for (Integer key : hashMap.keySet()) {
      String value = hashMap.get(key);
      Log.i(TAG, "key: " + key +"value: "+value);
 }

  long end2 = System.currentTimeMillis();
  Log.e(TAG, "鍵找值遍歷 cost time : " + (end2 - start2));

keySet迭代器遍歷線程

long start3 = System.currentTimeMillis();

Iterator<Integer> iterator=hashMap.keySet().iterator();
        while (iterator.hasNext()) {
        Integer key=iterator.next();
        String  value=hashMap.get(key);
        Log.i(TAG, "key: " + key +"value: "+value);
    }

 long end3 = System.currentTimeMillis();
 Log.e(TAG, "keySet iterator迭代器 cost time : " + (end3 - start3));

 上述四種狀況執行結果以下:

總結:

  主要從新熟悉一下Map這種數據結構,以及更好的在之後的編程中選擇更合適的方式來進行key-value存儲。

相關文章
相關標籤/搜索