Java集合類(一) HashMap、Map、LinkedHashMap、TreeMap


今天在做一個數據讀取分析的時候發現了一個問題。按序put進HashMap,取值的時候不是按序獲得的。
1,有可能是遍歷方法的問題。
a,keySet遍歷
for (String key : map.keySet()) {
System.out.println("key= "+ key + " and value= " + map.get(key));
} 失敗
b,通過Map.entrySet使用iterator遍歷key和value
Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, String> entry = it.next();
System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
} 失敗
c,Entry遍歷
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
} 失敗

   d,正常遍歷
      for (String v : map.values()) {
          System.out.println("value= " + v);
      }      失敗

所有能想到的遍歷方法都是用完了,發現還是沒有解決問題!那么可能就是Map內部的原理導致的非按序存儲。
2,查看HashMap原理
// 存儲時:
int hash = key.hashCode();
int index = hash % Entry[].length;
Entry[index] = value;

  // 取值時:
   int hash = key.hashCode();
   int index = hash % Entry[].length;
   return Entry[index];
 簡單的講,Map是一種結合數組和鏈表的優點的數據結構。

d

通過上圖的原理示意,其實我們可以畫出來我們的數據在HashMap中的存儲結構圖。需要注意的就是Entry里除了key和value之外還有一個next,這個next相當於鏈表中的鏈域指針。那什么情況下會用到next呢。很明顯當數據的hash值對map表長度去余時,結果相等。那么為了避免覆蓋,所以將數據按照插入時的順序鏈接到后邊。
下面就可以回答為什么按序put無序get的問題了。get的時候,首先是遍歷數組的第一個元素,然后遍歷第一個元素的鏈表。然后第二個元素,第二個元素的鏈表。。。。。So,我get到的數據極有可能是無序的了(相對於put的順序)。

  對於LinkedHashMap和TreeMap。LinkedHashMap與HashMap不同之處在於,它保留了一個‘前驅鏈域’和一個后繼鏈域。get的時候是按照put的順序讀取的。
 1 HashMap里面存入的鍵值對在取出的時候是隨機的,也是我們最常用的一個Map.它根據鍵的HashCode值存儲數據,根據鍵可以直接獲取它的值,具有很快的訪問速度。在Map 中插入、刪除和定位元素,HashMap 是最好的選擇。  
 2.TreeMap取出來的是排序后的鍵值對。但如果您要按自然順序或自定義順序遍歷鍵,那么TreeMap會更好。  
 3. LinkedHashMap 是HashMap的一個子類,如果需要輸出的順序和輸入的相同,那么用LinkedHashMap可以實現


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM