一、什麼是Map:
首先map是一個集合,一種按照鍵儲存元素的容器。在map中鍵可以是任意型別的物件,map中不能有重複的鍵,每一個鍵都有一個對應的值。
二、Map集合的特點:
1、Map是一個雙列集合,一個元素包含兩個值,一個key和一個value
2、Map集合中的元素,key和value的資料型別可以相同也可以不同
3、Map中的元素,key不允許重複,但是value可以重複
4、Map裡面的key和value是一一對應的
三、Map常用的實現類
HashMap:特點
1、首先hashmap底層是雜湊表,查詢速度非常快。
版本差異:JDK1.8之前是陣列+單向連結串列,JDK1.8之後是陣列+連結串列+紅黑樹,當單向連結串列長度超過8時,就轉換成紅黑樹
2、hashmap是無序的集合,儲存元素和取出元素的順序有可能不一致
3、hashmap不是執行緒安全的,因為當key衝突的時候,就需要把多個value放在同一個位置,jdk1.7以前就是通過連結串列的方式掛在同一個位置上,jdk1.8以後就是通過平衡樹的方式來代替連結串列的方式,當我們多個執行緒同時插入資料庫的時候就會出現執行緒不安全,當我們插入一個value節點會進行判斷是否為空,這時候多個執行緒都判斷為空,那麼後插入的資料就會在節點上面覆蓋前插入的資料,並沒有掛在後面。雖然不是執行緒安全的,但是速度快,效率高。
HashMap常用方法:
put(K key,V value):向集合中新增元素
實現原理:當我們向集合中新增元素的時候,先根據key值呼叫hsahCode方法,得到hashCode值,再根據與運算得到map中陣列的下標,然後判斷這個位置是否為空,若為空,則新增,
若不為空,則判斷是連結串列還是紅黑樹,如果是連結串列,那麼遍歷連結串列判斷連結串列長度是否大於8,大於8則轉換成紅黑樹插入鍵值對,小於8則判斷key值是否相同,若不同則插入,若相同則替換value,
如果是紅黑樹,那麼直接插入鍵值對。
1 package collection; 2 3 import java.util.HashMap; 4 5 public class MapTest { 6 public static void main(String[] args) { 7 HashMap<String, Integer> map = new HashMap<>(); 8 map.put("張三",25);//向map中新增元素 9 } 10 }
注:由於HashMap中的key是唯一的,因此在使用put方法向集合中新增元素時,一般不能新增相同的key,否則會新新增元素的value值會覆蓋原來的value值。
1 package collection; 2 3 4 import java.util.HashMap; 5 6 public class MapTest { 7 public static void main(String[] args) { 8 HashMap<String, Integer> map = new HashMap<>(); 9 map.put("張三",25);//向map中新增元素 10 System.out.println("原Value"+map.get("張三")); 11 map.put("張三",24); 12 System.out.println("新Value"+map.get("張三")); 13 System.out.println(map.size()); 14 } 15 }
輸出結果:
get(Object key):返回指定鍵所對映的值,如果沒有key所對應的value,那麼返回null
size()返回map中元素的數量
clear()清空map集合
isEmpty()判斷map集合中是否有資料,沒有返回true,有返回false
remove(Object key)刪除map集合中鍵為key的資料,並返回其所對應的value值
values()返回map集合中所有value組成的資料
HashMap遍歷方式:
1 package collection; 2 3 4 import java.util.HashMap; 5 import java.util.Iterator; 6 import java.util.Map; 7 import java.util.Set; 8 9 public class MapTest { 10 public static void main(String[] args) { 11 Map<String, Integer> map = new HashMap<>(); 12 map.put("張三",25);//向map中新增元素 13 map.put("李四",24); 14 //第一種遍歷方式 15 Set<Map.Entry<String, Integer>> entries = map.entrySet(); 16 for (Map.Entry<String, Integer> m: entries) { 17 System.out.println(m.getKey()+m.getValue()); 18 } 19 //第二種遍歷方式 20 Iterator<Map.Entry<String, Integer>> iterator = entries.iterator(); 21 while (iterator.hasNext()){ 22 System.out.println(iterator.next()); 23 } 24 } 25 }
由上圖看出linkedHashMap繼承自hashmap,那麼很多操作都應該建立在hashmap的基礎上,那麼與hashmap具體有哪些不同呢?
首先,linkedHashMap是雜湊表+連結串列的一種結構。特點:LinkedHashMap是一個有序的集合,儲存元素和取出元素的順序一致
1 package collection; 2 3 import java.util.HashMap; 4 import java.util.Iterator; 5 import java.util.LinkedHashMap; 6 import java.util.Map; 7 8 public class Linked { 9 public static void main(String[] args) { 10 Map<String, String> map = new LinkedHashMap<String,String>(); 11 map.put("a3", "aa"); 12 map.put("a2", "bb"); 13 map.put("b1", "cc"); 14 Iterator iterator = map.values().iterator(); 15 while (iterator.hasNext()){ 16 System.out.println(iterator.next());//aa bb cc 17 } 18 } 19 public static void main(String[] args) { 20 Map<String, String> map = new HashMap<String, String>(); 21 map.put("a3", "aa"); 22 map.put("a2", "bb"); 23 map.put("b1", "cc"); 24 for (Iterator iterator = map.values().iterator(); iterator.hasNext();) { 25 String name = (String) iterator.next(); 26 System.out.println(name);//bb aa cc 27 } 28 } 29 }
從以上程式碼結果可以看出,linkedHashMap在於儲存資料如果你想保持存進去的順序和拿出來的順序一致,優先考慮linkedHashMap。
那麼不同之處:就是hashmap無序,而linkedHashMap有序。
TreeMap:
TreeMap儲存的也是K-Value鍵值對,是通過紅黑樹實現,紅黑樹天然支援排序,預設情況下通過key值的自然排序進行排序
TreeMap中的put方法為Map的核心方法,實現原理為:呼叫put方法,先判斷紅黑樹是否已建,根節點是否為null,如果沒有則建立紅黑樹賦值給root,接下來遍歷紅黑樹節點,與傳入的key值進行比較,然後判斷是否有相同的key值,如果有相同的key,則替換value,如果沒有則遍歷到最後的節點作為插入節點的父節點,在父節點下插入位元組點。
總結:TreeMap中的元素是從小到大的順序排列的。TreeMap是基於紅黑樹實現的,根據鍵key的自然順序進行排序,也可以根據Comparator進行排序,具體取決於使用的構造方法。
HashTable:
HashTable是雜湊表,又叫做雜湊表,是根據鍵值對直接訪問的資料結構。
說到資料結構,那麼我們對兩種資料結構非常熟悉,陣列和連結串列,當然陣列的特點是查詢快,增刪慢,而連結串列的特點是增刪快,查詢慢,那麼把它兩結合起來是不是不但增刪快,查詢也快呢。
雜湊表就是兩者結合起來的產物。
hashTable與HashMap的不同之處:
1、基類不同,HashTable繼承Dictionary類,hashMap繼承AbstractMap類
2、hashMap可以允許存在一個為null的key和任意個為null的value,但是hashTable中的key和value都不允許為null。
3、hashmap不是執行緒安全的,hashtable是執行緒安全的,因為hashtable的方法是Synchronize修飾的,而HashMap不是。
使用場景:
hashmap適用於Map插入,刪除和定位元素
hashTable是執行緒安全的,效率比hashmap效率要低
TreeMap適用於按自然順序或自定義順序遍歷鍵key