亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

常見的HashMap迭代方式有哪些

發布時間:2022-02-28 16:59:19 來源:億速云 閱讀:201 作者:iii 欄目:開發技術

這篇文章主要介紹了常見的HashMap迭代方式有哪些的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇常見的HashMap迭代方式有哪些文章都會有所收獲,下面我們一起來看看吧。

一、 HashMap介紹

HashMap簡介:HashMap 是一個散列表,它存儲的內容是鍵值對(key-value)映射。HashMap 繼承于AbstractMap,實現了MapCloneablejava.io.Serializable接口。HashMap 的實現不是同步的,這意味著它不是線程安全的。它的keyvalue都可以為null。此外,HashMap中的映射不是有序的。HashMap 的實例有兩個參數影響其性能:“初始容量” 和 “加載因子”。容量 是哈希表中桶的數量,初始容量 只是哈希表在創建時的容量。加載因子 是哈希表在其容量自動增加之前可以達到多滿的一種尺度。當哈希表中的條目數超出了加載因子與當前容量的乘積時,則要對該哈希表進行rehash操作(即重建內部數據結構),從而哈希表將具有大約兩倍的桶數。 通常,默認加載因子是 0.75, 這是在時間和空間成本上尋求一種折衷。加載因子過高雖然減少了空間開銷,但同時也增加了查詢成本(在大多數 HashMap 類的操作中,包括 getput 操作,都反映了這一點)。在設置初始容量時應該考慮到映射中所需的條目數及其加載因子,以便最大限度地減少 rehash 操作次數。如果初始容量大于最大條目數除以加載因子,則不會發生 rehash 操作。

HashMap的構造函數

HashMap共有4個構造函數,如下:

// 默認構造函數。
HashMap()
// 指定“容量大小”的構造函數
HashMap(int capacity)
// 指定“容量大小”和“加載因子”的構造函數
HashMap(int capacity, float loadFactor)
// 包含“子Map”的構造函數
HashMap(Map<? extends K, ? extends V> map)

二、JDK7 中 HashMap 底層原理

HashMapJDK7 或者 JDK8 中采用的基本存儲結構都是數組+鏈表形式。

上圖中左邊橙色區域是哈希表,右邊藍色區域為鏈表,鏈表中的元素類型為 Entry,它包含四個屬性分別是:

  • K key

  • V value

  • int hash

  • Entry next

那么為什么會出現數組+鏈表形式的存儲結構呢?這里簡單地闡述一下,后續將以源碼的形式詳細介紹。 我們在使用 HashMap.put("Key", "Value")方法存儲數據的時候,底層實際是將keyvalueEntry的形式存儲到哈希表中,哈希表是一個數組,那么它是如何將一個 Entry 對象存儲到數組中呢?是如何確定當前 keyvalue 組成的 Entry 該存到數組的哪個位置上,換句話說是如何確定 Entry 對象在數組中的索引的呢?通常情況下,我們在確定數組的時候,都是在數組中挨個存儲數據,直到數組全滿,然后考慮數組的擴容,而 HashMap 并不是這么操作的。在 Java 及大多數面向對象的編程語言中,每個對象都有一個整型變量 hashcode,這個 hashcode 是一個很重要的標識,它標識著不同的對象,有了這個 hashcode,那么就很容易確定 Entry 對象的下標索引了,在 Java 語言中,可以理解 hashcode 轉化為數組下標是按照數組長度取模運算的,基本公式如下所示:

int index = HashCode(key) % Array.length

實際上,在 JDK 中哈希函數并沒有直接采取取模運算,而是利用了位運算的方式來提高性能,在這里我們理解為簡單的取模運算。 我們知道了對 Key 進行哈希運算然后對數組長度進行取模就可以得到當前 Entry 對象在數組中的下標,那么我們可以一直調用 HashMapput 方法持續存儲數據到數組中。但是存在一種現象,那就是根據不同的 Key 計算出來的結果有可能會完全相同,這種現象叫作“哈希沖突”。既然出現了哈希沖突,那么發生沖突的這個數據該如何存儲呢?哈希沖突其實是無法避免的一個事實,既然無法避免,那么就應該想辦法來解決這個問題,目前常用的方法主要是兩種,一種是開放尋址法,另外一種是鏈表法。 開放尋址法是原理比較簡單,就是在數組里面“另謀高就”,嘗試尋找下一個空檔位置。而鏈表法則不是尋找下一個空檔位置,而是繼續在當前沖突的地方存儲,與現有的數據組成鏈表,以鏈表的形式進行存儲。HashMap 的存儲形式是數組+鏈表就是采用的鏈表法來解決哈希沖突問題的。具體的詳細說明請繼續往下看。 在日常開發中,開發者對于 HashMap 使用的最多的就是它的構造方法、put 方法以及get 方法了,下面就開始詳細地從這三個方法出發,深入理解HashMap 的實現原理。

三、HashMap put、get 方法流程圖

上面中 get 流程圖畫得稍微比正常的要復雜一些,只是為了描述流程更加清晰。

四、常見的 HashMap 的迭代方式

在實際開發過程中,我們對于 HashMap 的迭代遍歷也是常見的操作,HashMap 的迭代遍歷常用方式有如下幾種:

  • 方式一:迭代器模式

Map<String, String> map = new HashMap<>(16);
Iterator<Map.Entry<String, String>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
    Map.Entry<String, String> next = iterator.next();
    System.out.println(next.getKey() + ":" + next.getValue());
}
  • 方式二:遍歷 Set>方式

Map<String, String> map = new HashMap<>(16);
for (Map.Entry<String, String> entry : map.entrySet()) {
    System.out.println(entry.getKey() + ":" + entry.getValue());
}
  • 方式三:forEach 方式(JDK8 特性,lambda)

Map<String, String> map = new HashMap<>(16);
map.forEach((key, value) -> System.out.println(key + ":" + value));
  • 方式四:keySet 方式

Map<String, String> map = new HashMap<>(16);
Iterator<String> keyIterator = map.keySet().iterator();
while (keyIterator.hasNext()) {
    String key = keyIterator.next();
    System.out.println(key + ":" + map.get(key));
}

把這四種方式進行比較,前三種其實屬于同一種,都是迭代器遍歷方式,如果要同時使用到 keyvalue,推薦使用前三種方式,如果僅僅使用到 key,那么推薦使用第四種。

關于“常見的HashMap迭代方式有哪些”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“常見的HashMap迭代方式有哪些”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

湄潭县| 筠连县| 泰和县| 江都市| 罗平县| 民权县| 轮台县| 上林县| 榆社县| 三门峡市| 长子县| 渝北区| 凉城县| 茂名市| 嘉峪关市| 双牌县| 罗山县| 叙永县| 吉隆县| 石狮市| 丰县| 磴口县| 海盐县| 桐柏县| 玉山县| 江西省| 新宾| 科技| 清河县| 登封市| 吉林省| 沽源县| 万源市| 溧阳市| 微山县| 玛曲县| 宁远县| 灵宝市| 富平县| 绥芬河市| 会理县|