Java集合類常見面試知識點總結

Java集合類學習總結

這篇總結是基於以前博客內容的一個整理和回顧。html

這裏先簡單地總結一下,更多詳細內容請參考個人專欄:深刻淺出Java核心技術 程序員

https://blog.csdn.net/column/details/21930.html面試

裏面有包括Java集合類在內的衆多Java核心技術系列文章。算法

如下總結不保證全對,若有錯誤,還望可以指出,謝謝。後端

最後,若是想要更好地完成這部份內容的學習,建議你們仍是去看一下原文。api

Colletion,iterator,comparable數組

通常認爲Collection是最上層接口,可是hashmap實際上實現的是Map接口。iterator是迭代器,是實現iterable接口的類必需要提供的一個東西,可以使用for(i : A) 這種方式實現的類型能提供迭代器,之前有一個enumeration,如今早棄用了。緩存

List

List接口下的實現類有ArrayList,linkedlist,vector等等,通常就是用這兩個,用法很少說,老生常談。安全

ArrayList的擴容方式是1.5倍擴容,這樣擴容避免2倍擴容可能浪費空間,是一種折中的方案。 另外他不是線程安全,vector則是線程安全的,它是兩倍擴容的。微信

linkedlist是雙鏈表,而且很坑的一點是,Java裏的linkedlist自帶按索引訪問的api,結果我沒用過,面試的時候被問到答錯了,致使我美團直接涼涼= =。

除此以外還有一個copyonwritelist,用於線程安全的場景。

Map

map永遠都是重頭戲。

1 hashmap是數組和鏈表的組合結構,數組是一個Entry數組,entry是k-V鍵值對類型,因此一個entry數組存着很entry節點,一個entry的位置經過key的hashcode方法,再進行hash(移位等操做),最後與表長-1進行相與操做,其實就是取hash值到的後n - 1位,n表明表長是2的n次方。

2 hashmap的默認負載因子是0.75,閾值是16 * 0.75 = 12;初始長度爲16;

3 hashmap的增刪改查方式比較簡單,都是遍歷,替換。有一點要注意的是key相等時,替換元素,不相等時連成鏈表。

4 除此以外,1.8jdk改進了hashmap,當鏈表上的元素個數超過8個時自動轉化成紅黑樹,節點變成樹節點,以提升搜索效率和插入效率到logn。

5 還有一點值得一提的是,hashmap的擴容操做,因爲hashmap非線程安全,擴容時若是多線程併發進行操做,則可能有兩個線程分別操做新表和舊錶,致使節點成環,查詢時會造成死鎖。chm避免了這個問題。

6 另外,擴容時會將舊錶元素移到新表,原來的版本移動時會有rehash操做,每一個節點都要rehash,很是不方便,而1.8改爲另外一種方式,對於同一個index下的鏈表元素,因爲一個元素的hash值在擴容後只有兩種狀況,要麼是hash值不變,要麼是hash值變爲原來值+2^n次方,這是由於表長翻倍,因此hash值取後n位,第一位要麼是0要麼是1,因此hash值也只有兩種狀況。這兩種狀況的元素分別加到兩個不一樣的鏈表。這兩個鏈表也只須要分別放到新表的兩個位置便可,是否是很酷。

7 最後有一個比較冷門的知識點,hashmap1.7版本鏈表使用的是節點的頭插法,擴容時轉移鏈表仍然使用頭插法,這樣的結果就是擴容後鏈表會倒置,而hashmap.1.8在插入時使用尾插法,擴容時使用頭插法,這樣能夠保證順序不變。

CHM

concurrenthashmap也稍微提一下把,chm1.7使用分段鎖來控制併發,每一個segment對應一個segmentmask,經過key的hash值相與這個segmentmask獲得segment位置,而後在找到具體的entry數組下標。

因此chm須要維護多個segment,每一個segment對應一段數組。分段鎖使用的是reetreetlock可重入鎖實現,查詢時不加鎖。

1.8則放棄使用分段鎖,改用cas+synchronized方式實現併發控制,查詢時不加鎖,插入時若是沒有衝突直接cas到成功爲止,有衝突則使用synchronized插入。

Set

set就是hashmap將value固定爲一個object,只存key元素,包裝成一個entry便可,其餘不變。

Linkedhashmap

在原來hashmap基礎上將全部的節點依據插入的次序另外連成一個鏈表。用來保持順序,可使用它實現lru緩存,當訪問命中時將節點移到隊頭,當插入元素超過長度時,刪除隊尾元素便可。

使用的時候先繼承linkedhashmap或者直接使用linkedhashmap做爲成員變量,而後重寫removeEldestEntry方法便可,注意傳入size參數,判斷當元素個數超過size時返回true,表示能夠刪除就好了。

collections和Arrays工具類

兩個工具類分別操做集合和數組,能夠進行經常使用的排序,合併等操做。

comparable和comparator

實現comparable接口可讓一個類的實例互相使用compareTo方法進行比較大小,能夠自定義比較規則,comparator則是一個通用的比較器,比較指定類型的兩個元素之間的大小關係。

這個東西仍是很好用的,作算法題的時候常常會用到自定義的排序方式。

treemap和treeset

主要是基於紅黑樹實現的兩個數據結構,能夠保證key序列是有序的,獲取sortedset就能夠順序打印key值了。其中涉及到紅黑樹的插入和刪除,調整等操做,比較複雜,這裏就不細說了。

另外咱們也能夠獲取逆序的set集合。

其餘

集合類要學的東西其實還不少,可是面試的東西可能就這麼多了把。固然可能還有一些遺漏,可是大部分我在面試中能遇到的問題都已經包含進去了。

微信公衆號

我的公衆號:黃小斜

黃小斜是跨考軟件工程的 985 碩士,自學 Java 兩年,拿到了 BAT 等近十家大廠 offer,從技術小白成長爲阿里工程師。

做者專一於 JAVA 後端技術棧,熱衷於分享程序員乾貨、學習經驗、求職心得和程序人生,目前黃小斜的CSDN博客有百萬+訪問量,知乎粉絲2W+,全網已有10W+讀者。

黃小斜是一個斜槓青年,堅持學習和寫做,相信終身學習的力量,但願和更多的程序員交朋友,一塊兒進步和成長!

原創電子書: 關注公衆號【黃小斜】後回覆【原創電子書】便可領取我原創的電子書《菜鳥程序員修煉手冊:從技術小白到阿里巴巴Java工程師》

程序員3T技術學習資源: 一些程序員學習技術的資源大禮包,關注公衆號後,後臺回覆關鍵字 「資料」 便可免費無套路獲取。

考研複習資料: 計算機考研大禮包,都是我本身考研複習時用的一些複習資料,包括公共課和專業的複習視頻,這裏也推薦給你們,關注公衆號後,後臺回覆關鍵字 「考研」 便可免費獲取。

技術公衆號:Java技術江湖

若是你們想要實時關注我更新的文章以及分享的乾貨的話,能夠關注個人公衆號【Java技術江湖】一位阿里 Java 工程師的技術小站,做者黃小斜,專一 Java 相關技術:SSM、SpringBoot、MySQL、分佈式、中間件、集羣、Linux、網絡、多線程,偶爾講點Docker、ELK,同時也分享技術乾貨和學習經驗,致力於Java全棧開發!

Java工程師必備學習資源: 一些Java工程師經常使用學習資源,關注公衆號後,後臺回覆關鍵字 「Java」 便可免費無套路獲取。

個人公衆號

本文由博客一文多發平臺 OpenWrite 發佈!

相關文章
相關標籤/搜索