容器

  1. ArrayList
    0. 通過(guò)數(shù)組實(shí)現(xiàn)
    1. add蜻韭,會(huì)進(jìn)行擴(kuò)容(當(dāng)前數(shù)組大小 + (當(dāng)前數(shù)組大小 / 2))
    2. remove臀栈,刪除對(duì)應(yīng)的下標(biāo)月腋,并通過(guò)System.arraycopy進(jìn)行數(shù)組平移
    3. 不能使用for循環(huán)進(jìn)行數(shù)組的刪除妄迁,因?yàn)閯h除數(shù)組會(huì)平移疗韵,應(yīng)該使用迭代器
    4. 多線程并發(fā)不能使用ArrayList兑障,要使用CopyOnWriteArrayList
    5. 添加多,查找少應(yīng)該使用LinkedList,避免頻繁copy

  2. LinkedList
    0. 通過(guò)雙向鏈表實(shí)現(xiàn)
    1. add直接在末尾添加一個(gè)Node
    2. remove流译,通過(guò)遍歷記數(shù)找到對(duì)應(yīng)的下標(biāo)逞怨。index < (size >> 1)如果是前半段則順序查找,如果是后半段則倒序查找
    3. 修改多福澡,應(yīng)該用LinkedList叠赦。查詢多則使用ArrayList

  3. CopyOnWriteArrayList
    1. 底層原理與ArrayList相似
    2. 線程安全
    3. 每次數(shù)組操作都是通過(guò)拷貝新數(shù)組進(jìn)行操作,然后再賦值回去
    4. add革砸,通過(guò)ReentrantLock + 數(shù)組拷貝 + volatile實(shí)現(xiàn)線程安全除秀。通過(guò)ReentrantLock加鎖,volatile實(shí)現(xiàn)內(nèi)存共享算利,數(shù)組拷貝觸發(fā)內(nèi)存地址變更册踩,同步其他線程
    5. 盡量使用addAll和removeAll,來(lái)進(jìn)行批量操作效拭,因?yàn)槊看蝍dd或remove都會(huì)進(jìn)行一次數(shù)組拷貝暂吉。

  4. hashMap
    0. 數(shù)組 + 鏈表 + 紅黑樹(shù)實(shí)現(xiàn)
    1. 當(dāng)鏈表長(zhǎng)度大于8鏈表轉(zhuǎn)為紅黑樹(shù),當(dāng)紅黑樹(shù)大小小于等于6時(shí)允耿,變回鏈表借笙。(紅黑樹(shù)的出現(xiàn)是為了解決鏈表過(guò)長(zhǎng)的問(wèn)題)
    2. put的實(shí)現(xiàn)過(guò)程:1. 對(duì)key計(jì)算Hash值(計(jì)算公式:hash = (h = key.hashCode()) ^ (h >>> 16)) 2. 通過(guò)計(jì)算((n - 1) & hash)獲得數(shù)組的下標(biāo),如果對(duì)應(yīng)的下標(biāo)中沒(méi)有值较锡,則直接進(jìn)行賦值业稼。如果有值,意味著發(fā)生了hash沖突蚂蕴,需要解決沖突低散。 3. 出現(xiàn)沖突時(shí)首先判斷key是否相等,內(nèi)存地址是否相等骡楼。如果都相等熔号,那就直接覆蓋。 4. 如果key不相等鸟整,則先判斷當(dāng)前的node引镊,如果是紅黑樹(shù),則根據(jù)紅黑樹(shù)的規(guī)則直接插入篮条。如果是鏈表弟头,則直接插入鏈表末尾。如果鏈表長(zhǎng)度大于等于8且數(shù)組長(zhǎng)度大于64涉茧,則擴(kuò)展為紅黑樹(shù)赴恨。
    3. 為什么鏈表長(zhǎng)度是8?
    因?yàn)楫?dāng)鏈表長(zhǎng)度為8時(shí)伴栓,鏈表的沖突概率已經(jīng)很小了伦连。為了處理特殊情況(大于等于8)就轉(zhuǎn)為紅黑樹(shù)雨饺。雖然紅黑樹(shù)的訪問(wèn)復(fù)雜度是O(LogN),鏈表的是O(n)惑淳,紅黑樹(shù)比鏈表訪問(wèn)要快额港,但是紅黑樹(shù)的內(nèi)存占用是鏈表的2倍。
    4. 擴(kuò)容算法(參考
    jdk1.7:在插入元素時(shí)汛聚,判斷如果當(dāng)前元素(鍵值對(duì))個(gè)數(shù)超過(guò)閾值锹安,并且出現(xiàn)了hash沖突,此時(shí)會(huì)進(jìn)行擴(kuò)容倚舀,將數(shù)組變?yōu)樵瓉?lái)的兩倍叹哭,并且所有元素重新計(jì)算hash,放到新的數(shù)組中痕貌。因?yàn)?.7中元素的鏈表插入是采用的頭插法风罩,所以多線程下會(huì)出現(xiàn)死循環(huán)的問(wèn)題。
    jdk1.8:擴(kuò)容是發(fā)生在插入元素之后舵稠。如果插入的鏈表后超升,鏈表個(gè)數(shù)是7個(gè),那么就會(huì)進(jìn)行擴(kuò)容哺徊,如果數(shù)組長(zhǎng)度超過(guò)64室琢,則當(dāng)前鏈表改為紅黑樹(shù),如果沒(méi)有超過(guò)64落追,則數(shù)組的大小變?yōu)樵瓉?lái)的2倍盈滴。如果鏈表個(gè)數(shù)沒(méi)有達(dá)到7個(gè),則判斷hashMap的元素個(gè)數(shù)是否超過(guò)閾值(size > 0.75 * 16)轿钠,如果超過(guò)了巢钓,同樣進(jìn)行擴(kuò)容(之后擴(kuò)大數(shù)組的容量,不會(huì)轉(zhuǎn)換紅黑樹(shù))疗垛。
    5. 調(diào)用 new HashMap(1000) 構(gòu)造方法症汹,內(nèi)部還會(huì)擴(kuò)容嗎?
    會(huì)的贷腕,因?yàn)镠ashMap的構(gòu)造參數(shù)中還有一個(gè)加載因子(0.75)背镇,所以實(shí)際上容量不到1000,后續(xù)還需要擴(kuò)容泽裳。加載因子的作用是判斷HashMap內(nèi)部是否需要擴(kuò)容芽世。即當(dāng)內(nèi)部容量達(dá)到1000 * 0.75 = 750之后,就會(huì)擴(kuò)容诡壁,而不是達(dá)到1000才擴(kuò)容。擴(kuò)容之后荠割,空間變大了妹卿,hash沖突降低了旺矾。

  5. ArrayMap
    0. 由兩個(gè)數(shù)組組成的Map
    1. 數(shù)組1存放hash值,數(shù)組2存放key+value
    2. get夺克,通過(guò)計(jì)算hash找到對(duì)應(yīng)的下標(biāo)箕宙,再通過(guò)二分查找,找到hash對(duì)應(yīng)的key/value
    3. put铺纽,通過(guò)計(jì)算hash找到數(shù)組2中的下標(biāo)柬帕,如果對(duì)應(yīng)下標(biāo)沒(méi)有值,直接插入狡门。如果有值陷寝,則插入到后面,后面的數(shù)組統(tǒng)一后移
    4. 緩存機(jī)制:緩存數(shù)組長(zhǎng)度為4或者8的數(shù)組其馏,每個(gè)上限10個(gè)凤跑。目的:為了減少頻繁創(chuàng)建和銷(xiāo)毀數(shù)組對(duì)象。

  6. ConcurrentHashMap
    0. 通過(guò)volatile修飾Map叛复,保證其在內(nèi)存中的可見(jiàn)性仔引,確保線程同步
    1. 在putValue時(shí),通過(guò)for循環(huán)和CAS自旋確保不會(huì)出現(xiàn)同步問(wèn)題
    2. 在擴(kuò)容時(shí)褐奥,會(huì)通過(guò)狀態(tài)確保擴(kuò)容過(guò)程
    3. 在操作節(jié)點(diǎn)時(shí)咖耘,通過(guò)synchronized鎖住節(jié)點(diǎn)

  7. LinkedBlockingQueue和ArrayBlockingQueue
    在隊(duì)列存放滿后,存數(shù)據(jù)的線程會(huì)進(jìn)入阻塞撬码,等待空間儿倒。
    在隊(duì)列為空時(shí),取數(shù)據(jù)的線程會(huì)進(jìn)入阻塞耍群,等待新的數(shù)據(jù)到來(lái)义桂。
    通過(guò)AQS的await進(jìn)行阻塞,通過(guò)signal進(jìn)行喚醒

    名字 底層實(shí)現(xiàn) 容量大小
    LinkedBlockingQueue 使用鏈表實(shí)現(xiàn) Int.MAX_VALUE
    ArrayBlockingQueue 使用數(shù)組實(shí)現(xiàn) 需要初始化時(shí)指定容量
  8. LRU數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)(https://mp.weixin.qq.com/s?__biz=MzU4NDE3MTEyMA==&mid=2247490403&idx=1&sn=dd361a87d74eec4ca9ef97efe016c906
    雙向鏈表 + HashMap

參考資料:
面試官: 我必問(wèn)的容器知識(shí)點(diǎn)! - 掘金 (juejin.cn)
Carson帶你學(xué)Java:手把手帶你源碼分析 HashMap 1.7
重讀源碼之 SparseArray 和 ArrayMap

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蹈垢,一起剝皮案震驚了整個(gè)濱河市慷吊,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌曹抬,老刑警劉巖溉瓶,帶你破解...
    沈念sama閱讀 218,122評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異谤民,居然都是意外死亡堰酿,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)张足,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)触创,“玉大人,你說(shuō)我怎么就攤上這事为牍『甙螅” “怎么了岩馍?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,491評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)抖韩。 經(jīng)常有香客問(wèn)我蛀恩,道長(zhǎng),這世上最難降的妖魔是什么茂浮? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,636評(píng)論 1 293
  • 正文 為了忘掉前任双谆,我火速辦了婚禮,結(jié)果婚禮上席揽,老公的妹妹穿的比我還像新娘顽馋。我一直安慰自己,他們只是感情好驹尼,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,676評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布趣避。 她就那樣靜靜地躺著,像睡著了一般新翎。 火紅的嫁衣襯著肌膚如雪程帕。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,541評(píng)論 1 305
  • 那天地啰,我揣著相機(jī)與錄音愁拭,去河邊找鬼。 笑死亏吝,一個(gè)胖子當(dāng)著我的面吹牛岭埠,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蔚鸥,決...
    沈念sama閱讀 40,292評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼惜论,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了止喷?” 一聲冷哼從身側(cè)響起馆类,我...
    開(kāi)封第一講書(shū)人閱讀 39,211評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎弹谁,沒(méi)想到半個(gè)月后乾巧,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,655評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡预愤,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,846評(píng)論 3 336
  • 正文 我和宋清朗相戀三年沟于,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片植康。...
    茶點(diǎn)故事閱讀 39,965評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡旷太,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出销睁,到底是詐尸還是另有隱情泳秀,我是刑警寧澤标沪,帶...
    沈念sama閱讀 35,684評(píng)論 5 347
  • 正文 年R本政府宣布,位于F島的核電站嗜傅,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏檩赢。R本人自食惡果不足惜吕嘀,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,295評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望贞瞒。 院中可真熱鬧偶房,春花似錦、人聲如沸军浆。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,894評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)乒融。三九已至掰盘,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間赞季,已是汗流浹背愧捕。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,012評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留申钩,地道東北人次绘。 一個(gè)月前我還...
    沈念sama閱讀 48,126評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像撒遣,于是被迫代替她去往敵國(guó)和親邮偎。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,914評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容