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

Java容器HashMap與HashTable詳解

 更新時(shí)間:2017年04月14日 09:16:02   作者:siqq  
本文主要介紹HashMap 和 Hashtable的工作原理和使用方法,有興趣的朋友可以參考

1、HashMap

HashMap繼承抽象類(lèi)AbstractMap,實(shí)現(xiàn)接口Map、Cloneable, Serializable接口。HashMap是一種以鍵值對(duì)存儲(chǔ)數(shù)據(jù)的容器,

由數(shù)組+鏈表組成,其中key和value都可以為空,key的值唯一。HashMap是非線程安全的, 對(duì)于鍵值對(duì)<Key,Value>,

HashMap內(nèi)部會(huì)將其封裝成一個(gè)對(duì)應(yīng)的Entry<Key,Value>對(duì)象。HashMap的存儲(chǔ)空間大小是可以動(dòng)態(tài)改變的:

存儲(chǔ)過(guò)程

每個(gè)對(duì)象都有一個(gè)對(duì)應(yīng)的HashCode值,根據(jù)HashCode值,調(diào)用hash函數(shù),計(jì)算出一個(gè)hash值,根據(jù)該hash值調(diào)用indexFor函數(shù),計(jì)算出在table中的存儲(chǔ)位置,如果該位置已經(jīng)有值,則存儲(chǔ)在該位置對(duì)應(yīng)的桶中。

 public V put(K key, V value) {
  if (table == EMPTY_TABLE) {
   inflateTable(threshold);
  }
  if (key == null)
   return putForNullKey(value);
  int hash = hash(key);
  int i = indexFor(hash, table.length);
  for (Entry<K,V> e = table[i]; e != null; e = e.next) {
   Object k;
   if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
    V oldValue = e.value;
    e.value = value;
    e.recordAccess(this);
    return oldValue;
   }
  }
  modCount++;
  addEntry(hash, key, value, i);
  return null;
 }
 public final int hash(Object k) {
  int h = hashSeed;
  if (0 != h && k instanceof String) {
   return sun.misc.Hashing.stringHash32((String) k);
  }
  h ^= k.hashCode();
  // This function ensures that hashCodes that differ only by
  // constant multiples at each bit position have a bounded
  // number of collisions (approximately 8 at default load factor).
  h ^= (h >>> 20) ^ (h >>> 12);
  return h ^ (h >>> 7) ^ (h >>> 4);
 }
 public final int hashCode() {
  return Objects.hashCode(getKey()) ^ Objects.hashCode(getValue()) 
 }
 static int indexFor(int h, int length) {
  // assert Integer.bitCount(length) == 1 : "length must be a non-zero power of 2";
  return h & (length-1);
 }

獲取值

首先根據(jù)key的HashCode碼計(jì)算出hash值,然后調(diào)用indexFor函數(shù)計(jì)算該entry對(duì)象在table中的存儲(chǔ)位置,遍歷該位置對(duì)應(yīng)桶中存儲(chǔ)的entry對(duì)象,如果存在對(duì)象的hash值和key與要查找的相同,則返回該對(duì)象。

 public final Entry<K,V> getEntry(Object key) {
  if (size == 0) {
   return null;
  }
  int hash = (key == null) ? 0 : hash(key);
  for (Entry<K,V> e = table[indexFor(hash, table.length)];
    e != null;
    e = e.next) {
   Object k;
   if (e.hash == hash &&
    ((k = e.key) == key || (key != null && key.equals(k))))
    return e;
  }
  return null;
 }

兩map相等的判斷

 public final boolean equals(Object o) {
   if (!(o instanceof Map.Entry))
    return false;
   Map.Entry e = (Map.Entry)o;
   Object k1 = getKey();
   Object k2 = e.getKey();
   if (k1 == k2 || (k1 != null && k1.equals(k2))) {
    Object v1 = getValue();
    Object v2 = e.getValue();
    if (v1 == v2 || (v1 != null && v1.equals(v2)))
     return true;
   }
   return false;
  }

自反性:對(duì)于任何非空引用值 x,x.equals(x) 都應(yīng)返回 true。


對(duì)稱(chēng)性:對(duì)于任何非空引用值 x 和 y,當(dāng)且僅當(dāng) y.equals(x) 返回 true 時(shí),x.equals(y) 才應(yīng)返回 true。

傳遞性:對(duì)于任何非空引用值 x、y 和 z,如果 x.equals(y) 返回 true,并且 y.equals(z) 返回

true,那么 x.equals(z) 應(yīng)返回 true。

一致性:對(duì)于任何非空引用值 x 和 y,多次調(diào)用 x.equals(y) 始終返回 true 或始終返回 false,前提是對(duì)象上

equals 比較中所用的信息沒(méi)有被修改。

對(duì)于任何非空引用值 x,x.equals(null) 都應(yīng)返回 false。

存儲(chǔ)空間動(dòng)態(tài)分配

HashMap的桶數(shù)目,即Entry[] table數(shù)組的長(zhǎng)度,由于數(shù)組是內(nèi)存中連續(xù)的存儲(chǔ)單元,它的空間代價(jià)是很大的,但是它的隨機(jī)存取的速度是Java集合中最快的。我們?cè)龃笸暗臄?shù)量,而減少Entry<Key,Value>鏈表的長(zhǎng)度,來(lái)提高從HashMap中讀取數(shù)據(jù)的速度。這是典型的拿空間換時(shí)間的策略。

但是我們不能剛開(kāi)始就給HashMap分配過(guò)多的桶(即Entry[] table 數(shù)組起始不能太大),這是因?yàn)閿?shù)組是連續(xù)的內(nèi)存空間,它的創(chuàng)建代價(jià)很大,況且我們不能確定給HashMap分配這么大的空間,它實(shí)際到底能夠用多少,為了解決這一個(gè)問(wèn)題,HashMap采用了根據(jù)實(shí)際的情況,動(dòng)態(tài)地分配桶的數(shù)量。

要?jiǎng)討B(tài)分配桶的數(shù)量,這就要求要有一個(gè)權(quán)衡的策略了,HashMap的權(quán)衡策略是這樣的:

如果 HashMap的大小 > HashMap的容量(即Entry[] table的大小)*加載因子(經(jīng)驗(yàn)值0.75)

 則 HashMap中的Entry[] table 的容量擴(kuò)充為當(dāng)前的一倍;然后重新將以前桶中的`Entry<Key,Value>`鏈表重新分配到各個(gè)桶中

上述的 HashMap的容量(即Entry[] table的大小) * 加載因子(經(jīng)驗(yàn)值0.75)就是所謂的閥值(threshold)。

2、HashTable

HashTable繼承Dictionary類(lèi),實(shí)現(xiàn)Map, Cloneable,Serializable接口,不允許key為空,采用拉鏈法實(shí)現(xiàn)與HashMap類(lèi)似。

 HashTable是線程安全的(但是在Collections類(lèi)中存在一個(gè)靜態(tài)方法:synchronizedMap(),該方法創(chuàng)建了一個(gè)線程安全的Map對(duì)象,通過(guò)該方法我們可以同步訪問(wèn)潛在的HashMap,對(duì)整個(gè)map對(duì)象加鎖。CurrentHashMap是線程安全的,并且只對(duì)桶加鎖,不會(huì)影響map對(duì)象上其它桶的操作)。

希望本文對(duì)各位朋友有所幫助

相關(guān)文章

  • Spring中的@CrossOrigin注冊(cè)處理方法源碼解析

    Spring中的@CrossOrigin注冊(cè)處理方法源碼解析

    這篇文章主要介紹了Spring中的@CrossOrigin注冊(cè)處理方法源碼解析,@CrossOrigin是基于@RequestMapping,@RequestMapping注釋方法掃描注冊(cè)的起點(diǎn)是equestMappingHandlerMapping.afterPropertiesSet(),需要的朋友可以參考下
    2023-12-12
  • SpringBoot+Redis實(shí)現(xiàn)接口防刷的示例代碼

    SpringBoot+Redis實(shí)現(xiàn)接口防刷的示例代碼

    在實(shí)際開(kāi)發(fā)中,會(huì)出現(xiàn)用戶多次點(diǎn)擊發(fā)送請(qǐng)求,本文主要介紹了SpringBoot+Redis實(shí)現(xiàn)接口防刷的示例代碼,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-01-01
  • java定時(shí)任務(wù)Timer和TimerTask使用詳解

    java定時(shí)任務(wù)Timer和TimerTask使用詳解

    這篇文章主要為大家詳細(xì)介紹了java定時(shí)任務(wù)Timer和TimerTask使用方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-02-02
  • java高級(jí)用法之JNA中的Structure

    java高級(jí)用法之JNA中的Structure

    這篇文章主要介紹了java高級(jí)用法之JNA中的Structure,JNA提供了Structure類(lèi),來(lái)幫助我們進(jìn)行這些映射處理,下面文章詳細(xì)的介紹過(guò)程需要的小伙伴可以參考一下
    2022-04-04
  • SpringBoot讀取配置文件的四種方式

    SpringBoot讀取配置文件的四種方式

    在 Spring Boot 中,application.yml 文件用于配置應(yīng)用程序的屬性,Spring Boot 默認(rèn)會(huì)從 src/main/resources 目錄下的 application.properties 或 application.yml 文件中讀取配置,本文介紹了SpringBoot讀取配置文件的四種方式,需要的朋友可以參考下
    2024-08-08
  • Java的volatile和sychronized底層實(shí)現(xiàn)原理解析

    Java的volatile和sychronized底層實(shí)現(xiàn)原理解析

    文章詳細(xì)介紹了Java中的synchronized和volatile關(guān)鍵字的底層實(shí)現(xiàn)原理,包括字節(jié)碼層面、JVM層面的實(shí)現(xiàn)細(xì)節(jié),以及鎖的類(lèi)型和MESI協(xié)議在多核處理器中的作用,文章還探討了synchronized和volatile的區(qū)別,以及如何通過(guò)Atomic類(lèi)來(lái)實(shí)現(xiàn)更細(xì)粒度的原子操作,感興趣的朋友一起看看吧
    2025-03-03
  • 解決SpringCloud Gateway采用OpenFeign遠(yuǎn)程調(diào)用失敗的問(wèn)題

    解決SpringCloud Gateway采用OpenFeign遠(yuǎn)程調(diào)用失敗的問(wèn)題

    在使用SpringCloud網(wǎng)關(guān)進(jìn)行統(tǒng)一鑒權(quán)和認(rèn)證過(guò)程中,通過(guò)OpenFeign遠(yuǎn)程調(diào)用鑒權(quán)服務(wù)器接口時(shí)可能會(huì)遇到遠(yuǎn)程調(diào)用失敗的問(wèn)題,這通常是因?yàn)镠ttpMessageConverters沒(méi)有被正確注入到Spring容器中
    2024-09-09
  • Spring Boot如何使用Undertow代替Tomcat

    Spring Boot如何使用Undertow代替Tomcat

    這篇文章主要介紹了Spring Boot如何使用Undertow代替Tomcat,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09
  • Java多線程 Guarded Suspension設(shè)計(jì)模式

    Java多線程 Guarded Suspension設(shè)計(jì)模式

    這篇文章主要介紹了Java多線程 Guarded Suspension設(shè)計(jì)模式,Guarded Suspension意為保護(hù)暫停,其核心思想是僅當(dāng)服務(wù)進(jìn)程準(zhǔn)備好時(shí),才提供服務(wù),文章圍繞Java多線程 Guarded Suspension展開(kāi)內(nèi)容,需要的朋友可以參考一下
    2021-10-10
  • Java中使用Jedis操作Redis的實(shí)現(xiàn)代碼

    Java中使用Jedis操作Redis的實(shí)現(xiàn)代碼

    本篇文章主要介紹了Java中使用Jedis操作Redis的實(shí)現(xiàn)代碼。詳細(xì)的介紹了Redis的安裝和在java中的操作,具有一定的參考價(jià)值,有興趣的可以了解一下
    2017-05-05

最新評(píng)論

新龙县| 大庆市| 海林市| 乐业县| 德昌县| 电白县| 民权县| 滁州市| 南陵县| 齐齐哈尔市| 阜城县| 巴马| 柏乡县| 宜兰县| 防城港市| 平江县| 青冈县| 台中市| 青川县| 天门市| 兴和县| 剑川县| 垦利县| 宽甸| 永寿县| 泉州市| 灵寿县| 小金县| 青州市| 大同市| 阳江市| 卢龙县| 新化县| 佛学| 嘉黎县| 建湖县| 珠海市| 靖州| 永安市| 西华县| 庆城县|