您好,登錄后才能下訂單哦!
這篇文章主要為大家展示了“Java集合中Map接口的實現類有哪些”,內容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領大家一起研究并學習一下“Java集合中Map接口的實現類有哪些”這篇文章吧。
HashMap是 Map 接口使用頻率最高的實現類,允許使用null鍵和null值,與HashSet一樣,不保證映射的順序。
所有的key構成的集合是Set:無序的、不可重復的。所以,key所在的類要重寫equals()
和hashCode()
。
所有的value構成的集合是Collection:無序的、可重復的。所以,value所在的類
要重寫equals()
。
一個key-value
構成一個entry,所有的entry構成的集合是Set:無序的、不可重復的。
HashMap判斷兩個 key 相等的標準:兩個 key 通過 equals()
方法返回 true,hashCode()
值也相等。
HashMap判斷兩個 value 相等的標準:兩個 value 通過 equals()
方法返回 true。
HashMap map = new HashMap()
(以JDK1.7說明)
在實例化以后,底層就創建了長度為16的一維數組Entry[] table
。
map.put(key1,value1)
首先,調用key1所在類的hashCode()
計算key1哈希值,此哈希值經過某種算法計算以后,得到在Entry[]
數組中的存放位置。
如果此位置上的數據為空,此時的key1-value1
添加成功。----情況1
如果此位置上的數據不為空(意味著此位置上存在一個或多個數據(以鏈表形式存在)),則繼續比較key1和已經存在的一個或多個數據的哈希值:
如果key1的哈希值與已經存在的數據的哈希值都不相同,此時key1-value1
添加成功。----情況2
如果key1的哈希值和已經存在的某一個數據key2-value2
的哈希值相同,繼續比較:
調用key1所在類的equals(key2)
如果equals()
返回false:此時key1-value1
添加成功。----情況3
如果equals()
返回true:使用value1替換value2。
補充:關于情況2和情況3,此時key1-value1
和原來的數據以鏈表的方式存儲。
在不斷的添加過程中,會涉及到擴容問題,默認的擴容方式:擴容為原來容量的2倍,并將原有的數據復制過來。
JDK1.8相較于JDK1.7在底層實現方面的不同:
①new HashMap()
,底層還沒有創建一個長度為16的數組
②JDK1.8底層的數組是: Node[]
,而非Entry[]
③首次調用put()
方法時,底層才創建長度為16的數組Node[]
④形成鏈表結構時,新添加的key-value對在鏈表的尾部(七上八下)
⑤JDK1.7底層結構只有“數組+鏈表”,JDK1.8中底層結構為“數組+鏈表+紅黑樹”。
當數組的某一個索引位置上的元素以鏈表形式存在的數據個數>8且當前數組的長度>64時,此時此索引位置上的所有數據改為使用紅黑樹存儲。
DEFAULT_INITIAL_CAPACITY
: HashMap的默認容量,16MAXIMUM_CAPACITY
: HashMap的最大支持容量,2^30DEFAULT_LOAD_FACTOR
:HashMap的默認加載因子,0.75TREEIFY_THRESHOLD
:Bucket中鏈表長度大于該默認值8,轉化為紅黑樹UNTREEIFY_THRESHOLD
:Bucket中紅黑樹存儲的Node小于該默認值6,轉化為鏈表MIN_TREEIFY_CAPACITY
:桶中的Node被樹化時最小的hash表容量。(當桶中Node的數量大到需要變紅黑樹時,若hash表容量小于MIN_TREEIFY_CAPACITY時,此時應執行resize擴容操作這個MIN_TREEIFY_CAPACITY的值至少是TREEIFY_THRESHOLD的4倍為64。)table
:存儲元素的數組,總是2的n次冪entrySet
:存儲具體元素的集size
:HashMap中存儲的鍵值對的數量modCount
:HashMap擴容和結構改變的次數。threshold
:擴容的臨界值,=容量*填充因子loadFactor
:填充因子
LinkedHashMap 是 HashMap 的子類
在HashMap存儲結構的基礎上,使用了一對雙向鏈表來記錄添加元素的順序
與LinkedHashSet類似,LinkedHashMap 可以維護 Map 的迭代順序:迭代順序與 Key-Value 對的插入順序一致
TreeMap存儲 Key-Value 對時,需要根據 key 進行排序。TreeMap 可以保證所有的 Key-Value 處于有序狀態。
TreeSet底層使用紅黑樹結構存儲數據。
TreeMap 的 Key 的排序:
①自然排序:TreeMap 的所有的 Key 必須實現 Comparable 接口,而且所有
的 Key 應該是同一個類的對象,否則將會拋出 ClasssCastException。
②定制排序:創建 TreeMap 時,傳入一個 Comparator 對象,該對象負責對
TreeMap 中的所有 key 進行排序,此時不需要 Map的Key實現Comparable接口。
TreeMap判斷兩個key相等的標準:兩個key通過compareTo()方法或者compare()方法返回0。
import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.TreeMap; /** * @Author: Yeman * @Date: 2021-09-22-22:59 * @Description: */ class user implements Comparable{ String name; int age; public user(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "user{" + "name='" + name + '\'' + ", age=" + age + '}'; } @Override public int compareTo(Object o) { if (o instanceof user){ user other = (user) o; Integer nameResult = this.name.compareTo(other.name); if (nameResult == 0){ return Integer.compare(this.age,other.age); }else return nameResult; }else throw new RuntimeException("類型不匹配"); } } public class TreeMapTest { public static void main(String[] args) { Map map = new TreeMap(); map.put(new user("Tom",22),1); map.put(new user("Jim",18),2); map.put(new user("Marry",20),3); map.put(new user("Lily",16),4); map.put(new user("Tom",18),5); Set set = map.entrySet(); Iterator iterator = set.iterator(); while (iterator.hasNext()){ System.out.println(iterator.next()); } } }
import java.util.*; /** * @Author: Yeman * @Date: 2021-09-22-22:59 * @Description: */ class user { String name; int age; public user(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "user{" + "name='" + name + '\'' + ", age=" + age + '}'; } } public class TreeMapTest { public static void main(String[] args) { Comparator comparator = new Comparator() { @Override public int compare(Object o1, Object o2) { if (o1 instanceof user && o2 instanceof user) { user user1 = (user) o1; user user2 = (user) o2; Integer nameResult = user1.name.compareTo(user2.name); if (nameResult == 0) return Integer.compare(user1.age, user2.age); else return nameResult; } else throw new RuntimeException("類型不匹配"); } }; Map map = new TreeMap(comparator); map.put(new user("Tom",22),1); map.put(new user("Jim",18),2); map.put(new user("Marry",20),3); map.put(new user("Lily",16),4); map.put(new user("Tom",18),5); Set set = map.entrySet(); Iterator iterator = set.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); } } }
Hashtable是個古老的 Map 實現類,JDK1.0就提供了。不同于HashMap,
Hashtable是線程安全的。
Hashtable實現原理和HashMap相同,功能相同。底層都使用哈希表結構,查詢
速度快,很多情況下可以互用。
與HashMap不同,Hashtable 不允許使用 null 作為 key 和 value。
與HashMap一樣,Hashtable 也不能保證其中 Key-Value 對的順序。
Hashtable判斷兩個key相等、兩個value相等的標準,與HashMap一致。
Properties 類是 Hashtable 的子類,該對象用于處理屬性文件,由于屬性文件里的 key、value 都是字符串類型,所以 Properties 里的 key 和 value 都是字符串類型
存取數據時,建議使用setProperty(String key,String value)
方法和getProperty(String key)
方法
Properties pros = new Properties(); pros.load(new FileInputStream("jdbc.properties")); String user = pros.getProperty("user"); System.out.println(user);
以上是“Java集合中Map接口的實現類有哪些”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。