最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java集合之HashMap/hashTable詳解

 更新時間:2023年09月21日 08:50:32   作者:X-TIE  
這篇文章主要介紹了Java集合之HashMap/hashTable詳解,Map是映射鍵值的對象,map不能包含重復(fù)鍵:每個鍵最多只能映射一個值,它模擬了數(shù)學(xué)函數(shù)的抽象,需要的朋友可以參考下

HashMap/hashTable詳解

Map是映射鍵值的對象。map不能包含重復(fù)鍵:每個鍵最多只能映射一個值。它模擬了數(shù)學(xué)函數(shù)的抽象。

Map接口包括基本操作的方法(如put、get、remove、containsKey、containsValue、size和empty)、批量操作(如putAll和clear)和集合視圖(如keySet、entrySet和values)。Java平臺包含三個通用的映射實現(xiàn):HashMap、TreeMap和LinkedHashMap。

它們的行為和性能與Set接口部分中描述的HashSet、TreeSet和LinkedHashSet類似。

下面從HashMap和hashTable兩個容器分別介紹對比介紹一下。

下面我來分別看一下HashMap 和 hashTable 在無參構(gòu)造函數(shù)實例化的具體實例:

由上圖我們可以看到HashMap的無參數(shù)構(gòu)造函數(shù)new 了一個:容量為16,加載因子為0.75,閾值為12的容器。

而hashTable的無參數(shù)構(gòu)造函數(shù)則new 了一個:容量為11,加載因子為0.75,閾值為8的容器。

其中閾值為容量和加載因子的乘積,意思是如果容器到了這個值,那么就要實施擴容的機制了。下面我們看一下這兩個容器到了閾值分別是如何擴容的呢?

首先是HashMap的擴容機制:

從源碼上看,容器擴大了原容器的length*2倍。必須是2的冥。(2的幾次方)

里面還有一個判斷如果原來容器的容量已經(jīng)達到了最大值,那么就把閾值調(diào)整到最大值,然后把原數(shù)組數(shù)據(jù)映射到新的更大的數(shù)組當(dāng)中。這也就是說當(dāng)數(shù)據(jù)量過多并且知道最大值的時候為了避免哈希表被重新散列(防止內(nèi)部數(shù)據(jù)結(jié)構(gòu)頻繁被重新構(gòu)建)。

然后我們看一下hashTable是如何擴容的:

原容器的大小乘以2+1,保證得到的數(shù)據(jù)是一個奇數(shù)。那么到這了我們考慮一下為什么table擴容要求是奇數(shù),而map擴容必須是2的冥呢?

那么我們下面說一下HashMap的擴容機制以及確認元素位置的源碼,來分析一下為什么設(shè)計成2的冥:

通過位運算符保證初始容量一定是2的冥

為了防止hash碰撞,在Entry數(shù)組(單鏈表)中為了保證每一個位置只有一個元素,通過hash%table.length=bucketIndex,bucketIndex為元素具體的位置,這樣能夠均勻的分布到容器的各個位置且不會有重復(fù)的。對集合操作效率也高。那么我們看一下源碼中是如何找到元素具體的位置的:

為了減少碰撞HashMap是做了二次hash運算的。

h為最后計算的hash值,length為容器的容量。假設(shè)容量 = 16,我們計算一個hash值,來看一下h具體值為,并且我們計算一下indexFor的值是什么:

可以看到具體的hash值和在容器中的一個位置信息。

然后我們看一下,巧合的是根據(jù)我們的計算h & (length - 1) == h % length兩個等式正好相等。且

這個的位運算的效率更高,這個應(yīng)該就是容量必須為2的冪的原因。保證了數(shù)據(jù)分散的均勻。

并且通過二次hash減少碰撞,那么什么是碰撞呢?碰撞就是兩個數(shù)計算出來的hash值一樣,且equals e1.equals(e2)不相等,這樣在一個hash位置上就會存儲多個鏈表。在取值或者刪除數(shù)據(jù)元素的時候效率比較低。

上面就是說的HashMap的容量為什么是2的冥的原因,下面來介紹一下hashTable的初始容量為什么是11,以及擴容機制?

hashTable的key獲取hash為直接返回的當(dāng)前key的hashCode值例如:如果是一個String的lisi返回3322014。

通過拆分lisi為char數(shù)組元素,且每個值拿到ASCII值的十進制。31*hash + 當(dāng)前碼值。

直接計算當(dāng)前hash & long int的最大值%當(dāng)前容器的容量,獲得具體在容器中的位置。

int newCapacity = (oldCapacity << 1) + 1;這個是hashTable的一個擴容計算規(guī)則:保證了擴容后容量始終為奇數(shù)。

那么hashTable的擴容容量始終保證為奇數(shù)呢?

首先我猜測跟他的確認地址是有關(guān)系的,在就是由于hashTable全程加了同步鎖為線程安全的,為了性能更高的操作容器才會這么設(shè)置,這塊如果有小伙伴能講解的比較清楚也歡迎評論交流指導(dǎo)。

最后總結(jié)一下:哈希表的大小為素數(shù)時,簡單的取模哈希的結(jié)果會更加均勻,所以單從這一點上看,HashTable的哈希表大小選擇,似乎更高明些。但另一方面我們又知道,在取模計算時,如果模數(shù)是2的冪,那么我們可以直接使用位運算來得到結(jié)果,效率要大大高于做除法。所以從hash計算的效率上,又是HashMap更勝一籌。之所以不一樣是因為HashMap用的位移運算確認具體位置,而hashTable是直接用的模。(事實就是HashMap為了加快hash的速度,將哈希表的大小固定為了2的冪。當(dāng)然這引入了哈希分布不均勻的問題,所以HashMap為解決這問題,又對hash算法做了一些改動。HashMap和HashTable在計算hash時都用到了一個叫hashSeed的變量。這是因為映射到同一個hash桶內(nèi)的Entry對象,是以鏈表的形式存在的,而鏈表的查詢效率比較低,所以HashMap/HashTable的效率對哈希沖突非常敏感,所以可以額外開啟一個可選hash(hashSeed),從而減少哈希沖突。)

在結(jié)尾總結(jié)性的補充一下這個hashTable和HashMap的異同:

1.首先父類不同。hashTable的父類是Dictionary<K,V>,HashMap的父類是AbstractMap<K,V>.

2.HashMap是支持null鍵和null值的,而HashTable在遇到null時,會拋出NullPointerException異常。

3.初始化大小不同,擴容機制不同。

4.hashTable為線程安全的,方法級別的強制同步。HashMap非線程安全的。所以HashMap效率性能要高。

相同點:都實現(xiàn)了Map<K,V>接口。

到此這篇關(guān)于Java集合之HashMap/hashTable詳解的文章就介紹到這了,更多相關(guān)HashMap/hashTable詳解內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 微信公眾號開發(fā)之設(shè)置自定義菜單實例代碼【java版】

    微信公眾號開發(fā)之設(shè)置自定義菜單實例代碼【java版】

    這篇文章主要介紹了微信公眾號開發(fā)之設(shè)置自定義菜單實例代碼,本實例是為了實現(xiàn)在管理后臺實現(xiàn)微信菜單的添加刪除管理。需要的朋友可以參考下
    2018-06-06
  • SpringBoot集成免費的EdgeTTS實現(xiàn)文本轉(zhuǎn)語音

    SpringBoot集成免費的EdgeTTS實現(xiàn)文本轉(zhuǎn)語音

    在需要文本轉(zhuǎn)語音(TTS)的應(yīng)用場景中(如語音助手、語音通知、內(nèi)容播報等),Java生態(tài)缺少類似Python生態(tài)的Edge?TTS?客戶端庫,不過沒關(guān)系,現(xiàn)在可以通過?UnifiedTTS?提供的?API?來調(diào)用免費的?EdgeTTS?能力,本文給大家介紹了SpringBoot集成免費的EdgeTTS實現(xiàn)文本轉(zhuǎn)語音
    2025-10-10
  • 詳解spring中的Aware接口功能

    詳解spring中的Aware接口功能

    Spring的依賴注入的最大亮點是所有的Bean對Spring容器的存在是沒有意識的,我們可以將Spring容器換成其他的容器,Spring容器中的Bean的耦合度因此也是極低的,本文重點給大家介紹spring中的Aware接口,感興趣的朋友一起看看吧
    2022-02-02
  • SpringBoot使用@NotEmpty、@NotBlank、@NotNull注解進行參數(shù)校驗

    SpringBoot使用@NotEmpty、@NotBlank、@NotNull注解進行參數(shù)校驗

    我們經(jīng)常需要對請求參數(shù)進行校驗,本文主要介紹了SpringBoot使用@NotEmpty、@NotBlank、@NotNull注解進行參數(shù)校驗,具有一定的參考價值,感興趣的可以了解一下
    2024-08-08
  • SpringBoot中實現(xiàn)JSON轉(zhuǎn)Word格式的示例詳解

    SpringBoot中實現(xiàn)JSON轉(zhuǎn)Word格式的示例詳解

    這篇文章主要為大家詳細介紹了如何使用SpringBoot實現(xiàn)JSON轉(zhuǎn)Word格式,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-05-05
  • 詳解Java中的數(shù)組與字符串相關(guān)知識

    詳解Java中的數(shù)組與字符串相關(guān)知識

    這篇文章主要介紹了詳解Java中的數(shù)組與字符串相關(guān)知識,包括操作字符串的一些基本方法列舉,需要的朋友可以參考下
    2015-09-09
  • Mybatis中updateBatch實現(xiàn)批量更新

    Mybatis中updateBatch實現(xiàn)批量更新

    本文主要介紹了Mybatis中updateBatch實現(xiàn)批量更新,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • SpringBoot中@GetMapping注解的使用

    SpringBoot中@GetMapping注解的使用

    @GetMapping注解是Spring Boot中最常用的注解之一,它可以幫助開發(fā)者定義和處理HTTP GET請求,本文就來介紹一下SpringBoot中@GetMapping注解的使用,感興趣的可以了解一下
    2023-10-10
  • SpringBoot 中的異步處理機制詳解

    SpringBoot 中的異步處理機制詳解

    本文介紹了異步處理的基礎(chǔ)配置、線程池的自定義以及常見應(yīng)用場景,在實際應(yīng)用中,異步處理可以有效提升應(yīng)用的性能,改善用戶體驗,但同時也需要我們合理管理線程池,確保系統(tǒng)資源的高效利用,感興趣的朋友跟隨小編一起看看吧
    2025-01-01
  • Java后端Tomcat實現(xiàn)WebSocket實例教程

    Java后端Tomcat實現(xiàn)WebSocket實例教程

    WebSocket protocol 是HTML5一種新的協(xié)議。它實現(xiàn)了瀏覽器與服務(wù)器全雙工通信(full-duplex)。一開始的握手需要借助HTTP請求完成握手。本文給大家介紹Java后端Tomcat實現(xiàn)WebSocket實例教程,感興趣的朋友一起學(xué)習(xí)吧
    2016-05-05

最新評論

杭锦旗| 靖西县| 福泉市| 扶沟县| 铁力市| 建湖县| 安平县| 积石山| 建阳市| 左权县| 威海市| 嫩江县| 蓬溪县| 桃园县| 万载县| 普洱| 雷山县| 共和县| 黎城县| 石楼县| 杨浦区| 柳河县| 双城市| 太湖县| 永福县| 富宁县| 城口县| 桐乡市| 曲松县| 新丰县| 林口县| 岳阳市| 邯郸市| 蓬莱市| 奉节县| 神木县| 新邵县| 马公市| 东阳市| 潼南县| 闵行区|