久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Map接口及其重要實現(xiàn)類的用法

 Dragon_chen 2017-06-26

Map接口

   Map中的每個成員方法由一個關(guān)鍵字(key)和一個值(value)構(gòu)成。Map接口不直接繼承于Collection接口,因為它包裝的是一組成對的“鍵-值”對象的集合,,而且在Map接口的集合中也不能有重復(fù)的key出現(xiàn),,因為每個鍵只能與一個成員元素相對應(yīng)。

  Map接口的子接口以及主要實現(xiàn)類有:

子接口:Bindings,、ConcurrentMap,、ConcurrentNavigableMap、MessageContext,、LogicMessageContext,、NavigableMap、SOAPMessageMap,、SortedMap

實現(xiàn)類:AbstractMap, Attributes,AuthProvider, ConcurrentHashMap, EnumMap,ConcurrentSkipListMap,HashMapHashtable, IdentityHashMap, LinkedHashMap, PrinterStateReasons,Properties,Provider, RenderingHints, SimpleBindings, TabularDataSupport,TreeMap,UIDefaults,WeakHashMap


Map接口中定義的方法清單:

  Map中定義的方法說明:

在Map接口中定義的通用方法并不是很多,。

a)      添加和刪除Map中的某個元素

·        put(K, V) : 將給定的“鍵-值”對放入到給定的Map當中

·        putAll(Map<? extends K, ? extends V) : 將指定的Map中的“鍵-值”對放入到給定的Map當中

·        remove(Object key) : 從該集合中移除指定的對象,并返回對應(yīng)的value

·        clear() : 清空Map中的所有對象

b)      查詢與Map有關(guān)的數(shù)據(jù)

·        int size() : 返回此Map中“鍵-值”對的個數(shù)

·        boolean isEmpty() : 判斷此Map中“鍵-值”對的個數(shù)是否為0

·        boolean containsKey(Object key) : 測試此Map中是否有該key

·        boolean containsValue(Object value) : 測試此Map中是否包含該value

·        V get(Object key) : 通過指定的key查詢Map中對應(yīng)的value

·        Collection<Object value> values() : 取得Map中所有的value

·        Set<Object key> keySet() : 取得當前Map中key的集合

·        Set<Entry<K, V>> entrySet() : 取得當前Map中entry的集合

  HashMap的特點,、實現(xiàn)機制及使用方法

a)HashMap的特點:

HashMap實現(xiàn)了Map,、CloneMap、Serializable三個接口,,并且繼承自AbstractMap類,。

b)HashMap的實現(xiàn)機制:

HashMap基于hash數(shù)組實現(xiàn),若key的hash值相同則使用鏈表方式進行保存,,詳見HashSet中的說明,。我引用網(wǎng)上一個名詞叫“鏈表散列”來形容這樣的數(shù)據(jù)結(jié)構(gòu)

新建一個HashMap時會初始化一個大小為16,,負載因子為0.75的空的HashMap,。

  1. <span style="font-size:10px;">1.  /**  
  2. 2.    * The table, resized as necessary. Length MUST Always be a power of two.  
  3. 3.    */    
  4. 4.   transient Entry[] table;  </span>  


那么Entry到底是怎么實現(xiàn)的呢?

viewplainprint

1.  static class Entry<K,V> implements Map.Entry<K,V> {  

2.        final K key;  

3.        V value;  

4.        Entry<K,V> next;  

5.        final int hash;  

6.        ......  

上面代碼其實告訴我們Entry是一個結(jié)點,,它持有下一個元素的引用,,這樣就構(gòu)成了一個鏈表。

那么,,整體上來說HashMap底層就是使用這樣一個數(shù)據(jù)結(jié)構(gòu)來實現(xiàn)的,。

我們提到使用Hash,但是Hash值如何與元素的存儲建立關(guān)系呢,?(Hash算法

在數(shù)據(jù)結(jié)構(gòu)課中我們學(xué)習(xí)過Hash的簡單算法,,就是給你一個Hash因子,通過對該元素的hashCode簡單的求余,,來實現(xiàn)對其快速的定位和索引,。

在HashMap中有這樣的代碼:

viewplainprint

1.  /** 

2.    * Returns index for hash code h. 

3.    */  

4.  static int indexFor(int h, int length) {  

5.       return h & (length-1);  

6.  }  

這個方法在HashMap中非常重要,凡是與查詢,、添加,、刪除有關(guān)的方法中都有調(diào)用該方法,,為什么這么短的一個代碼使用率這么高?根據(jù)代碼注釋我們知道,,這個方法是根據(jù)hashCode及當前table的長度(數(shù)組的長度,,不是map的size)得到該元素應(yīng)該存放的位置,或者在table中的索引,。

現(xiàn)在我們需要看一下當數(shù)據(jù)量已經(jīng)超過初始定義的負載因子時,,HashMap如何處理?

在HashMap中當數(shù)據(jù)量很多時,,并且已經(jīng)達到了負載限度時,,會重新做一次哈希,也就是說會再散列,。調(diào)用的方法為resize(),,并且Java默認傳入的參數(shù)為2*table.length。先看一下JDK源碼:

  1. 1.  /**  
  2. 2.       * Rehashes the contents of this map into a new array with a  
  3. 3.       * larger capacity.  This method is called automatically when the  
  4. 4.       * number of keys in this map reaches its threshold.  
  5. 5.       *  
  6. 6.       * If current capacity is MAXIMUM_CAPACITY, this method does not  
  7. 7.       * resize the map, but sets threshold to Integer.MAX_VALUE.  
  8. 8.       * This has the effect of preventing future calls.  
  9. 9.       *  
  10. 10.      * @param newCapacity the new capacity, MUST be a power of two;  
  11. 11.      *        must be greater than current capacity unless current  
  12. 12.      *        capacity is MAXIMUM_CAPACITY (in which case value  
  13. 13.      *        is irrelevant).  
  14. 14.      */    
  15. 15.     void resize(int newCapacity) {    
  16. 16.         Entry[] oldTable = table;    
  17. 17.         int oldCapacity = oldTable.length;    
  18. 18.         if (oldCapacity == MAXIMUM_CAPACITY) {    
  19. 19.             threshold = Integer.MAX_VALUE;    
  20. 20.             return;    
  21. 21.         }    
  22. 22.     
  23. 23.         Entry[] newTable = new Entry[newCapacity];    
  24. 24.         transfer(newTable);    
  25. 25.         table = newTable;    
  26. 26.         threshold = (int)(newCapacity * loadFactor);    
  27. 27.     }    
  28. 28.     
  29. 29.     /**  
  30. 30.      * Transfers all entries from current table to newTable.  
  31. 31.      */    
  32. 32.     void transfer(Entry[] newTable) {    
  33. 33.         Entry[] src = table;    
  34. 34.         int newCapacity = newTable.length;    
  35. 35.         for (int j = 0; j < src.length; j++) {    
  36. 36.             Entry<K,V> e = src[j];    
  37. 37.             if (e != null) {    
  38. 38.                 src[j] = null;    
  39. 39.                 do {    
  40. 40.                     Entry<K,V> next = e.next;    
  41. 41.                     int i = indexFor(e.hash, newCapacity);    
  42. 42.                     e.next = newTable[i];    
  43. 43.                     newTable[i] = e;    
  44. 44.                     e = next;    
  45. 45.                 } while (e != null);    
  46. 46.             }    
  47. 47.         }    
  48. 48.     }    


看到這里我們會發(fā)現(xiàn)resize(再哈希)的工作量是不是很大啊,。再哈希是重新建一個指定容量的數(shù)組,,然后將每個元素重新計算它要放的位置,這個工作量確實是很大的,。

這里就產(chǎn)生了一個很重要的問題,那就是怎么讓哈希表的分布比較均勻,,也就是說怎么讓它即不會成為一個單鏈表(極限情況,,每個key的hash值都集中到了一起),又不會使hash空間過大(導(dǎo)致內(nèi)存浪費),?

上面兩個問題一個是解決了怎么計算hash值快速存取,,一個是怎么實現(xiàn)再哈希,何時需要再哈希,??焖俅嫒〉那疤崾窃胤植季鶆颍恢劣诩械揭稽c,,再哈希是元素過于零散,,導(dǎo)致不斷的重新構(gòu)建表。

那么在第一個問題中我們看到了這樣一個代碼return h & (length-1);在第二個問題中我們說過內(nèi)部調(diào)用傳入的值為2*table.length;并且默認情況下HashMap的大小為一個16的數(shù)字,,除了默認構(gòu)造提供大小為16的空間外,,如果我們使用

public HashMap(int initialCapacity,float loadFactor)

上面的構(gòu)造方法,我們會發(fā)現(xiàn)這樣的代碼:

viewplainprint

1.  // Find a power of 2 >= initialCapacity  

2.  int capacity = 1;  

3.  while (capacity < initialCapacity)  

4.        capacity <<= 1;  

5.  ……  

6.  table = new Entry[capacity];  

也就是說當我們傳入1000時,,它并沒有給我們構(gòu)造一個容量為1000的哈希表,,而是構(gòu)建了一個容量為1024大小的哈希表。

從整體上我們發(fā)現(xiàn)一個問題,,那就是無論什么情況HashMap中哈希表的容量總是2的n次方的一個數(shù),。并且有這樣一個公式:

       當length=2^n時,hashcode& (length-1) == hashcode % length

也就是這一點驗證了第一個問題,hash索引值的計算方法其實就是對哈希因子求余,。只有大小為2的n次方時,,那樣的計算才成立,所以HashMap為我們維護了一個這樣大小的一個哈希表,。(位運算速度比取模運算快的多)

c)      HashMap的使用方法:

我在很多代碼中都用到了HashMap,,原因是首先它符合存儲關(guān)聯(lián)數(shù)據(jù)的要求,其次它的存取速度快,,這是一個選擇的問題,。

比較重要的是HashMap的遍歷方法,KeySet,EntrySet。

總結(jié):

1.    HashMap采用數(shù)組方式存儲key,,value構(gòu)成的Entry對象,,無容量限制。

2.    HashMap基于key hash尋找Entry對象存放到數(shù)組的位置,,對于Hash沖突采用鏈表的方式來解決,。

3.    HashMap在插入元素時可能要擴大數(shù)組的容量,擴大容量時對所有的數(shù)據(jù)要重新計算哈希和存放到新數(shù)組中,。當元素個數(shù)size大于threshold擴容threshold = (int)(newCapacity* loadFactor);

4.    HashMap保證數(shù)組的大小為2的指數(shù)大小,。

5.    HashMap非線程安全。

  HashMap與Hashtable的區(qū)別:

1.        HashMap從java1.2后開始引進,。Hashtable從java1.0開始引入,。Hashtable一開始基于繼承陳舊的抽象類Dictionary實現(xiàn),后面也實現(xiàn)了Map接口。HashMap基于Map接口實現(xiàn),。

2.        HashMap允許存放key為null,,value為null。對于key為null時,,HashMap首先獲取Entry數(shù)組中的第一個Entry對象,,并基于Entry對象的next遍歷鏈表,當找到其中Entry對象的key屬性為null時,,更新其value值,。如果沒有key屬性為null的Entry,則調(diào)用addEntry(int hash, K key, V value, int bucketIndex),,參數(shù)為0,null,value,0,,增加一個Entry對象,增加時先獲取當前數(shù)組的第一個Entry對象,,記為e,,然后創(chuàng)建一個key為null,value為傳入值得得Entry對象,,next為之前獲取的e,。數(shù)組的第一個Entry對象鏈表,,賦為新創(chuàng)建的Entry對象。由此,,addEntry鏈表倒序插入元素的,。Hashtable不允許key為null或value為null,否則會拋出NullPointerException,。這從put方法的源碼中很容易看出來,,置于為什么真么限制,不明白,?

3.       HashMap是非線程安全,;Hashtable是線程安全的,其方法包含synchronized關(guān)鍵字實現(xiàn)線程安全,。

4.       HashMap的計算hash值方法如下:首先對key取其hashCode,然后通過如下計算:

h ^= (h >>> 20) ^ (h >>> 12);

        return h ^ (h >>> 7) ^ (h>>> 4);

最后取index時:return h &(length-1);

Hashtable計算hash值,,直接去key的hashCode值,如下:

int hash =key.hashCode();

取index時:int index = (hash& 0x7FFFFFFF) % tab.length;

5.   HashMap和Hashtable默認構(gòu)造時,,默認容量值不同,。

HashMap默認數(shù)組大小為16,加載因子為0.75,重新hash閾值為12.

Hashtable默認數(shù)組大小為11,加載因子為0.75,,重新hash閾值為8.

6.  HashMap和Hashtable的數(shù)組擴容方式不同,。

HashMap中的數(shù)組容量大小始終保證為2的指數(shù)。重新hash,擴充容量方式為,,當前容量大小*2.

Hashtable擴充容量方式為:int newCapacity = oldCapacity * 2 + 1;

7.  一些成員方法不同,。

Hashtable包含一些舊的方法,如contains方法,。

面試中常會碰到。

  LinkedHashMap的特點,、實現(xiàn)機制及使用方法

a)LinkedHashMap的特點:

LinkedHashMap繼承自HashMap并且實現(xiàn)了Map接口,。和HashMap一樣,LinkedHashMap允許key和value均為null,。

于該數(shù)據(jù)結(jié)構(gòu)和HashMap一樣使用到hash算法,,因此它不能保證映射的順序,尤其是不能保證順序持久不變(再哈希),。

如果你想在多線程中使用,,那么需要使用Collections.synchronizedMap方法進行外部同步,。

LinkedHashMap與HashMap的不同之處在于,,LinkedHashMap維護著運行于所有條目的雙向鏈接列表,此鏈接列表可以是插入順序或者訪問順序,。

b) LinkedHashMap的實現(xiàn)機制:


對于LinkedHashMap而言,,它繼承與HashMap,、底層使用哈希表與雙向鏈表來保存所有元素,。其基本操作與父類HashMap相似,它通過重寫父類相關(guān)的方法,,來實現(xiàn)自己的鏈接列表特性,。下面我們來分析LinkedHashMap的源代碼:

1)Entry元素:

   LinkedHashMap采用的hash算法和HashMap相同,但是它重新定義了數(shù)組中保存的元素Entry,,該Entry除了保存當前對象的引用外,,還保存了其上一個元素before和下一個元素after的引用,從而在哈希表的基礎(chǔ)上又構(gòu)成了雙向鏈接列表,??丛创a:

Java代碼  

1. /** 

2.  * 雙向鏈表的表頭元素。 

3.  */  

4. private transient Entry<K,V> header;  

5.   

6. /** 

7.  * LinkedHashMap的Entry元素,。 

8.  * 繼承HashMap的Entry元素,,又保存了其上一個元素before和下一個元素after的引用。 

9.  */  

10.private static class Entry<K,V> extends HashMap.Entry<K,V> {  

11.    Entry<K,V> before, after;  

12.    ……  

13.}  

2)初始化:

   通過源代碼可以看出,,在LinkedHashMap的構(gòu)造方法中,,實際調(diào)用了父類HashMap的相關(guān)構(gòu)造方法來構(gòu)造一個底層存放的table數(shù)組。如:

Java代碼  

1. public LinkedHashMap(int initialCapacity, float loadFactor) {  

2.     super(initialCapacity, loadFactor);  

3.     accessOrder = false;  

4. }  

    HashMap中的相關(guān)構(gòu)造方法:

Java代碼  

1. public HashMap(int initialCapacity, float loadFactor) {  

2.     if (initialCapacity < 0)  

3.         throw new IllegalArgumentException("Illegal initial capacity: " +  

4.                                            initialCapacity);  

5.     if (initialCapacity > MAXIMUM_CAPACITY)  

6.         initialCapacity = MAXIMUM_CAPACITY;  

7.     if (loadFactor <= 0 || Float.isNaN(loadFactor))  

8.         throw new IllegalArgumentException("Illegal load factor: " +  

9.                                            loadFactor);  

10.  

11.    // Find a power of 2 >= initialCapacity  

12.    int capacity = 1;  

13.    while (capacity < initialCapacity)  

14.        capacity <<= 1;  

15.  

16.    this.loadFactor = loadFactor;  

17.    threshold = (int)(capacity * loadFactor);  

18.    table = new Entry[capacity];  

19.    init();  

20.}  

    我們已經(jīng)知道LinkedHashMap的Entry元素繼承HashMap的Entry,,提供了雙向鏈表的功能,。在上述HashMap的構(gòu)造器
中,最后會調(diào)用init()方法,,進行相關(guān)的初始化,,這個方法在HashMap的實現(xiàn)中并無意義,只是提供給子類實現(xiàn)相關(guān)的初始化調(diào)用,。
   LinkedHashMap重寫了init()方法,,在調(diào)用父類的構(gòu)造方法完成構(gòu)造后,進一步實現(xiàn)了對其元素Entry的初始化操作,。

Java代碼  

1. void init() {  

2.     header = new Entry<K,V>(-1, nullnullnull);  

3.     header.before = header.after = header;  

4. }  

3)存儲:

   LinkedHashMap并未重寫父類HashMap的put方法,,而是重寫了父類HashMap的put方法調(diào)用的子方法void addEntry(int hash, Kkey, V value, int bucketIndex) 和voidcreateEntry(int hash, K key, V value, int bucketIndex),提供了自己特有的雙向鏈接列表的實現(xiàn),。

Java代碼  

1. void addEntry(int hash, K key, V value, int bucketIndex) {  

2.     // 調(diào)用create方法,,將新元素以雙向鏈表的的形式加入到映射中。  

3.     createEntry(hash, key, value, bucketIndex);  

4.   

5.     // 刪除最近最少使用元素的策略定義  

6.     Entry<K,V> eldest = header.after;  

7.     if (removeEldestEntry(eldest)) {  

8.         removeEntryForKey(eldest.key);  

9.     } else {  

10.        if (size >= threshold)  

11.            resize(2 * table.length);  

12.    }  

13.}  

Java代碼  

1. void createEntry(int hash, K key, V value, int bucketIndex) {  

2.     HashMap.Entry<K,V> old = table[bucketIndex];  

3.     Entry<K,V> e = new Entry<K,V>(hash, key, value, old);  

4.     table[bucketIndex] = e;  

5.     // 調(diào)用元素的addBrefore方法,,將元素加入到哈希,、雙向鏈接列表。  

6.     e.addBefore(header);  

7.     size++;  

8. }  

Java代碼  

1. private void addBefore(Entry<K,V> existingEntry) {  

2.     after  = existingEntry;  

3.     before = existingEntry.before;  

4.     before.after = this;  

5.     after.before = this;  

6. }  

4)讀?。?/span>

   LinkedHashMap重寫了父類HashMap的get方法,,實際在調(diào)用父類getEntry()方法取得查找的元素后,再判斷當排序模式accessOrder為true時,,記錄訪問順序,,將最新訪問的元素添加到雙向鏈表的表頭,,并從原來的位置刪除。由于的鏈表的增加,、刪除操作是常量級的,,故并不會帶來性能的損失。

Java代碼  

1. public V get(Object key) {  

2.     // 調(diào)用父類HashMap的getEntry()方法,,取得要查找的元素,。  

3.     Entry<K,V> e = (Entry<K,V>)getEntry(key);  

4.     if (e == null)  

5.         return null;  

6.     // 記錄訪問順序。  

7.     e.recordAccess(this);  

8.     return e.value;  

9. }  

Java代碼  

1. void recordAccess(HashMap<K,V> m) {  

2.     LinkedHashMap<K,V> lm = (LinkedHashMap<K,V>)m;  

3.     // 如果定義了LinkedHashMap的迭代順序為訪問順序,,  

4.     // 則刪除以前位置上的元素,,并將最新訪問的元素添加到鏈表表頭。  

5.     if (lm.accessOrder) {  

6.         lm.modCount++;  

7.         remove();  

8.         addBefore(lm.header);  

9.     }  

10.}  

5)排序模式:

   LinkedHashMap定義了排序模式accessOrder,,該屬性為boolean型變量,,對于訪問順序,為true,;對于插入順序,,則為false。

Java代碼  

1. private final boolean accessOrder;  

 一般情況下,,不必指定排序模式,,其迭代順序即為默認為插入順序??碙inkedHashMap的構(gòu)造方法,,如:

Java代碼  

1. public LinkedHashMap(int initialCapacity, float loadFactor) {  

2.     super(initialCapacity, loadFactor);  

3.     accessOrder = false;  

4. }  

    這些構(gòu)造方法都會默認指定排序模式為插入順序。如果你想構(gòu)造一個LinkedHashMap,,并打算按從近期訪問最少到近期訪問最多的順序(即訪問順序)來保存元素,,那么請使用下面的構(gòu)造方法構(gòu)造LinkedHashMap:

Java代碼  

1. public LinkedHashMap(int initialCapacity,  

2.          float loadFactor,  

3.                      boolean accessOrder) {  

4.     super(initialCapacity, loadFactor);  

5.     this.accessOrder = accessOrder;  

6. }  

    該哈希映射的迭代順序就是最后訪問其條目的順序,這種映射很適合構(gòu)建LRU緩存,。LinkedHashMap提供了removeEldestEntry(Map.Entry<K,V>eldest)方法,,在將新條目插入到映射后,put和 putAll將調(diào)用此方法,。該方法可以提供在每次添加新條目時移除最舊條目的實現(xiàn)程序,默認返回false,,這樣,,此映射的行為將類似于正常映射,即永遠不能移除最舊的元素,。

Java代碼  

1. protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {  

2.     return false;  

3. }  

    此方法通常不以任何方式修改映射,,相反允許映射在其返回值的指引下進行自我修改。如果用此映射構(gòu)建LRU緩存,,則非常方便,,它允許映射通過刪除舊條目來減少內(nèi)存損耗,。
   例如:重寫此方法,維持此映射只保存100個條目的穩(wěn)定狀態(tài),,在每次添加新條目時刪除最舊的條目,。

Java代碼  

1. private static final int MAX_ENTRIES = 100;  

2. protected boolean removeEldestEntry(Map.Entry eldest) {  

3.     return size() > MAX_ENTRIES;  

4. }  

總結(jié):

1.    LinkedHashMap繼承于HashMap,此鏈接列表定義了迭代順序,,該迭代順序可以是插入順序或者是訪問順序(按從近期訪問最少到近期訪問最多的順序),。默認情況下按插入順序訪問,當accessOrder設(shè)置為true時,,按最后訪問順序遍歷數(shù)據(jù),。

2.    LinkedHashMap非線程安全。

3.    LinkedHashMap適合做LRU緩存,。

TreeMap的特點:

  TreeMap是一個支持排序的基于紅黑樹(Red-Black tree)的NavigableMap實現(xiàn),,非線程安全。TreeMap繼承AbstractMap,實現(xiàn)NavigableMap,,NavigableMap接口繼承SortedMap接口,。此實現(xiàn)為 containsKey、get,、put 和 remove 操作提供受保證的 log(n) 時間開銷,。

    SortedMap提供關(guān)于鍵的總體排序的Map。該映射是根據(jù)其鍵的自然順序進行排序的,,或者根據(jù)通常在創(chuàng)建有序映射時提供的 Comparator 進行排序,。對有序映射的 collection 視圖(由 entrySet、keySet 和 values 方法返回)進行迭代時,,此順序就會反映出來,。

插入SortedMap的所有鍵都必須實現(xiàn) Comparable 接口(或者被指定的比較器接受)。另外,,所有這些鍵都必須是可互相比較的:對有序映射中的任意兩個鍵 k1 和 k2 執(zhí)行 k1.compareTo(k2)(或 comparator.compare(k1, k2))都不得拋出 ClassCastException,。試圖違反此限制將導(dǎo)致違反規(guī)則的方法或者構(gòu)造方法調(diào)用拋出 ClassCastException。

所有通用SortedMap實現(xiàn)類都應(yīng)該提供 4 個“標準”構(gòu)造方法:

1) void(無參數(shù))構(gòu)造方法,,它創(chuàng)建一個空的有序映射,,按照鍵的自然順序(實現(xiàn)Comparable接口,方法compareTo為自然比較方法,,按此方法比較大小排序)進行排序,。        2) 帶有一個 Comparator 類型參數(shù)的構(gòu)造方法,它創(chuàng)建一個空的有序映射,,根據(jù)指定的比較器進行排序,。

3) 帶有一個 Map 類型參數(shù)的構(gòu)造方法,它創(chuàng)建一個新的有序映射,,其鍵-值映射關(guān)系與參數(shù)相同,,按照鍵的自然順序進行排序,。

4) 帶有一個 SortedMap 類型參數(shù)的構(gòu)造方法,它創(chuàng)建一個新的有序映射,,其鍵-值映射關(guān)系和排序方法與輸入的有序映射相同,。無法保證強制實施此建議,因為接口不能包含構(gòu)造方法,。

SortedMap新增了一些成員方法,,如下圖所示:

NavigableMap<K,V>接口,擴展自 SortedMap,,具有了針對給定搜索目標返回最接近匹配項的導(dǎo)航方法,。方法 lowerEntry、floorEntry,、ceilingEntry 和 higherEntry 分別返回與小于,、小于等于、大于等于,、大于給定鍵的鍵關(guān)聯(lián)的 Map.Entry 對象,,如果不存在這樣的鍵,則返回 null,。類似地,,方法 lowerKey、floorKey,、ceilingKey 和 higherKey 只返回關(guān)聯(lián)的鍵,。所有這些方法是為查找條目而不是遍歷條目而設(shè)計的。

TreeMap實現(xiàn)機制:

TreeMap()

    將comparator屬性賦值為null,。如果要控制TreeMap中元素的存儲順序,,應(yīng)使用帶Comparator參數(shù)的構(gòu)造器。

put(K,V)

  先判斷root是否為null,,如果為null,,則創(chuàng)建一個新的Entry對象,并賦值給root屬性,。否則,,首先判斷是否傳入了Compatator實現(xiàn),如果是,,則基于紅黑樹的方式遍歷,,直到為樹節(jié)點null,使用傳入的comparator比較Key的大小,,如果找到相等的key則更新其值,若沒有找到……,,如果comparator為null,,則判斷key是否為null,,如果是null,拋出NullPointerException,,對于key不是null時,,取key對于的Comparator進行紅黑樹的遍歷和比較,與上述類似,。

如果沒有找到相同的key,,則創(chuàng)建一個新的Entry對象,并將其parent設(shè)置為上面所尋找到的元素,,并根據(jù)和parent key比較的情況設(shè)置parent的left和right屬性,。最后對紅黑樹進行調(diào)整。

ConcurrentHashMap的特點,,實現(xiàn)原理:

    ConcurrentHashMap是線程安全的HashMap實現(xiàn),。支持獲取,查找時完全并發(fā)和更新時可調(diào)整并發(fā)的哈希表,。獲取操作(包括 get)通常不會受阻塞,。并發(fā)場景中(多個線程的情況下) ConcurrentHashMap比HashMap優(yōu)秀很多。


    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多