面試題:Map原理及使用

2020-12-21 全棧技術資源社區

Hashmap

原理

hashmap的底層數據結構散列表,即:數組+鍊表,創建的時候初始化一個數組,每個節點可以為一個鍊表

當一鍵值對發生put操作時,

首先根據key的hash值得到這個元素在數組中的位置(即下標),如果這個位置上已經存在其他元素,將進行下一步操作。

由於同一點是鍊表方式存儲,會將原來的元素向後推然後新的元素放在這個位置上put操作可能會出現衝突,衝突分兩種:

不同的key值,通過hash函數得出相同的index,這種衝突通過上面所說的鍊表方式存儲。相同的key值,直接覆蓋。所以為了減少衝突,儘量將hashmap 的長度設置為2的次方,因為如果不是2的次方,經過hash & 操作,最後一位總是0如下圖,而0001,0011,0101,1001,1011,0111,1101這幾個位置永遠都不能存放元素了,空間浪費相當大,而且這樣可以使用的位置比數組長度小了很多,增加了衝突的機率,故減慢的查詢的效率(如果每一個節點都不存在鍊表,則不需要循環,查詢效率會高,所以儘量均勻分布)。

同理,當一鍵值對發生get操作時,會經過hash函數計算得到index,如果節點為鍊表有多個元素,則迭代用key.equals()比較獲取。

容量

源碼多了噁心,少量如下:

Java代碼

static final int DEFAULT_INITIAL_CAPACITY = 16; static final int MAXIMUM_CAPACITY = 1 << 30; static final float DEFAULT_LOAD_FACTOR = 0.75f; 三個常量中可以看出,默認的容器大小是16,最大長度是2的30次方,load factor默認是0.75,擴充的臨界值是16*0.75=12,

如果put操作檢測出hashmap的容量不足,就把數組的大小擴展為2*16=32,即擴大一倍,然後重新計算每個元素在數組中的位置,而這是一個非常消耗性能的操作,所以如果我們已經預知hashmap中元素的個數,那麼預設元個數能夠有效的提高hashmap的性能。

實戰總結

所以如果我們想初始化一個容量大小為13的容量,合理的方式是什麼呢?

1.Map<String, String> map1 = new HashMap<>(13);

2.Map<String, String> map2 = new HashMap<>(13, 1);

3.Map<String, String> map3 = Maps.newHashMapWithExpectedSize(13);

以上是三種初始化方式

第一種

直接根據構造方法初始化,那麼map會初始化一個容量大小為16的map,在超過16*0.75即12的時候發生擴容,這顯然不是我們想看到的。

第二種

在構造容量為13的基礎上,將負載因子的值設為1,那麼map將會在超過16個元素後開發擴容,可以滿足我們的預期效果,但這種情況一旦發生擴容,隨著元素的增多,碰撞的機率就會升高,鍊表就會很長,這樣就大大的降低了性能。

第三種

使用guava的方式初始化一個map,根據源碼發現guava已經幫我算好了,真正需要擴容的臨界點,

可以滿足我們的期望,同時也不需要修改負載因子的值,所以無特殊情況下,建議使用此方式。

LinkedHashMap

其底層實現基本與hashmap一致,但是linkedHashMap多維護了一張雙向的鍊表

LinkedHashMap成員變量

增加accessOrder屬性,默認為false,當為false時,按插入順序排序,當為true時,

按LRU+插入順序排序

LRU:最近最少使用算法

Entry

其保存的Entry對象增加了兩個屬性,before和after

存數據

LinkedHashMap沒有重寫put方法,而是重寫了addEntry()方法,把新的Entry也加到header

鍊表結構裡面去

取數據

1、先調用hashmap的getEntry()方法獲取Entry

當accessOrder為true時,把最近使用的當前Entry移到header的before位置,而LinkedHashIterator遍歷的方式是從header.after開始遍歷,先得到最近使用的Entry

最近使用:accessOrder為true時,get(Object key)方法會導致Entry最近使用put(K key, V value)/putForNullKey(value)只有是覆蓋操作時會導致Entry最近使用。它們都會觸發recordAccess方法從而導致Entry最近使用

刪除

LinkedHashMap沒有重寫remove(Object key)方法,重寫了被remove調用的recordRemoval方法,刪除了雙向鍊表中的before和after。

HahsMap remove(Object key)把數據從橫向數組 * 豎向next鍊表裡面移除之後(就已經完成工作了,所以HashMap裡面recordRemoval是空的實現調用了此方法

LinkedHashMap的遍歷

總結

1、什麼是LRU+插入順序?

put(K key, V value)/putForNullKey(value)只有覆蓋操作時會導致Entry最近使用,即為插入順序;accessOrder為true時,get(Object key)方法會導致Entry最近使用,即為LRU

2、LinkedHashMap和HashMap的區別

LinkedHashMap繼承HashMap,結構2裡數據結構的變化交給HashMap就行了。結構1裡數據結構的變化就由LinkedHashMap裡重寫的方法去實現。簡言之:LinkedHashMap比HashMap多維護了一個鍊表。

相關焦點

  • Java集合List和Map面試題以及答案
    Map集合它提供了一個鍵映射到值的一個數據結構,記住map的值是個重複,但鍵是唯一的,Map的子類有很多比如創建的是HashMap和LinkedHashMap。面試官常問的面試題1、Vector和Arraylist區別?
  • Map面試問題解讀,一篇就懂,清晰明了
    ,TreeMap 適合需要根據 key 進行排序的場景,LinkedHashMap 適合按照插入順序訪問,或需要刪除最少訪問元素的場景,剩餘場景我們使用 HashMap 即可,我們工作中大部分場景基本都在使用 HashMap;由於三種 map 的底層數據結構的不同,導致上層包裝的 api 略有差別。
  • 2020Web前端面試題匯總整理-開課吧
    2020Web前端開發面試題問題:有哪些常見的Plugin?解析:file-loader:把文件輸出到個文件夾中,在代碼中通過相對 URL 去引用輸出的文件 ;url-loader:和 file-loader 類似,但是能在文件很小的情況下以 base64 的方式把文件內容注入到代碼中去 source-map-loader:加載額外的
  • C++後端開發面試題與知識點匯總(附答案)
    以下匯總C++後臺開發面試題與知識點,還有其他崗位的相關題庫和資料,想要什麼崗位的可以留言哦~附面試題目:一、基礎知識1、基本語言說一下C++和C的區別與unordered_map請你說一說vector和list的區別,應用,越詳細越好請你來說一下STL中迭代器的作用,有指針為何還要迭代器請你說一說epoll原理n個整數的無序數組,找到每個元素後面比它大的第一個數
  • 拼多多2020屆數據分析面試題合集
    另外面試題具體是業務題多一點還是機器學習等題目多一點,這個也不太好說,主觀上是與你的簡歷或者面試官相關。不叭叭了,以下是從牛客給大家整理的多多的面試題,再次謝謝各位在牛客上給下一屆的同學留下面經的同學,祝大家工作順利,一切都好。
  • 搞定HashMap面試,深入講解HashMap的工作原理
    摘要:HashMap是近幾年java面試新秀,出場率高達80%以上,如此高頻的出場不得不讓碼農們慎重其事。但依舊拜倒在它的石榴裙下,讓面試場面一度尷尬。它也是開發中最常用到的key-value數據類型。
  • 來自朋友最近阿里、騰訊、美團等P7崗位面試題
    來自朋友最近阿里、騰訊、美團等P7崗位面試題
  • Java:按值對map進行排序
    在Java中,我們可以使用TreeMap該類通過其鍵對地圖進行排序。該類非常易於使用。但是,有時我們需要按其值對map進行排序。如何通過其值對映射進行排序是Java程式設計師最常問的問題。在本文中,我將開發編寫這種方法的最佳方法。
  • 計算機中的Map接口
    叫做HashMap,因此HashMap的實現原理即哈希表數據結構的實現原理。Map常用方法Map也是和List,Set一樣有增刪改查這幾個操作。例子:Map<String,String> map=new HashMap<String,String>();使用put方法增加操作。
  • 來複習一波,HashMap底層實現原理解析
    那麼我們能不能把以上兩種結合一起使用,從而實現查詢效率高和插入刪除效率也高的數據結構呢?答案是可以滴,那就是哈希表可以滿足,接下來我們一起複習HashMap中的put()和get()方法實現原理。HashMap的put()和get()的實現1、map.put(k,v)實現原理第一步
  • 四面阿里斬獲offer定級P7,2020最新最全阿里巴巴68道高級面試題
    面試:如果不準備充分的面試,完全是浪費時間,更是對自己的不負責。今天給大家分享下我整理的Java架構面試專題及答案(文末見面試答案),其中大部分都是大企業面試常問的面試題,可以對照這查漏補缺,當然了,這裡所列的肯定不可能覆蓋全部方式,不過也希望能對即將找工作的朋友起到一些幫助!
  • Java架構師常見基礎面試題(附答案)
    但你知道企業在招聘面試時會提問什麼嗎?接下來千鋒廣州Java小編就給大家分享一些基礎面試題答疑。1、什麼是Spring框架?Spring框架有哪些主要模塊?Spring框架是一個為Java應用程式的開發提供了綜合、廣泛的基礎性支持的Java平臺。
  • 面試技巧:怎樣在緊張情緒下答好題
    面試,是省考考試中尤為重要的考試環節,往年的省考面試一般在7月中旬左右進行,由於今年特殊的情況,具體的面試時間要根據山西省考公告為準。雖然公告未出,但同學們一定要抓緊時間備考了。很多同學諮詢小編,「我是第一次參加省考,面試都考些什麼呢?」,「我特別容易緊張,到時候面試我答不上來怎麼辦呢?」
  • 國家公務員面試2018年3月19日海關面試題
    【導讀】華圖國家公務員考試網同步華圖教育發布:國家公務員面試2018年3月19日海關面試題,詳細信息請閱讀下文!如有疑問請加【2021國家公務員考試微信客服】 ,更多資訊請關注寧夏華圖微信公眾號(ningxiaht),國家公務員培訓諮詢電話:0951-6028571/6027571 18295188220,微信號:HT15202602573   國家公務員面試2018年3月19日海關面試題   1.你是一名村官,所在村有很多閒置的農場和廠房,你決定把村裡的這些閒置農場
  • 科技行業年度十大最刁鑽古怪的面試題盤點
    站長之家(CHINAZ.com)12月28日編譯:如果你坐在美國一家高科技公司內等待面試時,期望面試官問的都是有關測試你的專業能力以及公司發展史之類的問題,那你就把招聘流程想得太過簡單了。
  • 遊戲製作人面試題匯總及個人思考
    常規流程面試題:1、你先做個自我介紹吧面試官角度:對於面試官來說,可能是臨時接到你這個面試,也可能是工作太忙,看完簡歷又忘了。所以需要候選人先做個自我介紹。面試問題是沒法窮舉的,但是可以針對每個問題進行舉一反三。最關鍵還是個人平常需要有積累和思考,才能以不變應萬變。面試題也只是幫助自己變得更好,而不是什麼矇混過關的奇淫巧技。
  • 2020國考面試模擬題:無人便利店
    國家公務員考試題庫:國家公務員網提供2020國考結構化面試模擬題每日一練、國家公務員面試題庫、歷年國家公務員面試題及答案,本文整理2020國考面試模擬題:無人便利店。【面試模擬題】隨著人工智慧的發展,新零售行業下衍生出無人便利店這一全新的商業模式。
  • 國家公務員面試2017年3月2日國稅系統面試題
    【導讀】華圖國家公務員考試網同步華圖教育發布:國家公務員面試2017年3月2日國稅系統面試題,詳細信息請閱讀下文!如有疑問請加【2021國家公務員考試微信客服】 ,更多資訊請關注寧夏華圖微信公眾號(ningxiaht),國家公務員培訓諮詢電話:0951-6028571/6027571 18295188220,微信號:HT15202602573   2017年3月2日國稅系統面試題   1.請你閱讀桌上的題籤(請考生注意,不要再題籤上寫字或做記號)
  • ThreadLocal的使用和實現原理
    ThreadLocal的使用和實現原理ThreadLocal是什麼?使用其實很簡單,保存值就調用set方法,獲得值調用get方法,最後調用remove方法刪除數據,防止內存洩漏和數據混亂。ThreadLocal的數據結構Thread類中有個變量threadLocals,這個類型為ThreadLocal中的一個內部類ThreadLocalMap,這個類沒有實現map接口,就是一個普通的Java類,但是實現的類似map的功能。