Java集合框架面試題
常見集合
集合可以看作是一種容器穷当,用來存儲(chǔ)對(duì)象信息闸昨。
數(shù)組和集合的區(qū)別:
(1)數(shù)組長度不可變化而且無法保存具有映射關(guān)系的數(shù)據(jù)挽唉;集合類用于保存數(shù)量不確定的數(shù)據(jù)塘秦,以及保存具有映射關(guān)系的數(shù)據(jù)。
(2)數(shù)組元素既可以是基本類型的值碌更,也可以是對(duì)象裕偿;集合只能保存對(duì)象。
Java集合類主要由兩個(gè)接口Collection和Map痛单。
Collection接口派生出來的常用集合有:
- (主要)ArrayList嘿棘、LinkedList
- (次要)HashSet、TreeSet旭绒、Vector(過去式)
Map接口派生出來的常用集合有: - (主要)HashMap
- (次要)TreeMap
簡要說明List鸟妙、Set、Map的區(qū)別
List集合:有序挥吵、可重復(fù)集合重父,集合中每個(gè)元素都有其對(duì)應(yīng)的順序索引。
實(shí)現(xiàn)List接口的集合主要有:ArrayList忽匈、LinkedList房午、Vector。
Set集合:有序丹允,不可重復(fù)集合郭厌,重復(fù)元素會(huì)覆蓋掉。
實(shí)現(xiàn)Set接口的集合主要有:HashSet雕蔽、TreeSet折柠。
Map集合:以鍵值對(duì)的方式存儲(chǔ),元素?zé)o存入順序批狐,元素不可重復(fù)扇售,重復(fù)元素會(huì)覆蓋掉,key、value都可以為null
實(shí)現(xiàn)Map接口的集合主要有:HashMap承冰、HashTable嘱根、TreeMap。
(1)ArrayList
ArrayList是一個(gè)動(dòng)態(tài)數(shù)組巷懈,也是我們最常用的集合,是List類的典型實(shí)現(xiàn)慌洪。它允許任何符合規(guī)則的元素插入甚至包括null顶燕。每一個(gè)ArrayList都有一個(gè)初始容量10,該容量代表了數(shù)組的大小冈爹。隨著容器中的元素不斷增加涌攻,容器的大小也會(huì)隨著增加。在每次向容器中增加元素的同時(shí)都會(huì)進(jìn)行容量檢查频伤,當(dāng)快溢出時(shí)恳谎,就會(huì)進(jìn)行擴(kuò)容操作。所以如果我們明確所插入元素的多少憋肖,最好指定一個(gè)初始容量值因痛,避免過多的進(jìn)行擴(kuò)容操作而浪費(fèi)時(shí)間、效率岸更。
(2)LinkedList
LinkedList是List接口的另一個(gè)實(shí)現(xiàn)鸵膏,除了可以根據(jù)索引訪問集合元素外,LinkedList還實(shí)現(xiàn)了Deque接口怎炊,可以當(dāng)作雙端隊(duì)列來使用谭企,也就是說,既可以當(dāng)作“椘浪粒”使用债查,又可以當(dāng)作隊(duì)列使用。
(3)Vector
與ArrayList相似瓜挽,但是Vector是同步的盹廷。所以說Vector是線程安全的動(dòng)態(tài)數(shù)組。它的操作與ArrayList幾乎一樣秸抚。
(4)HashSet
HashSet是不能保證元素的順序速和,不是線程同步的集合,如果多線程操作HashSet集合剥汤,則應(yīng)通過代碼來保證其同步颠放,集合元素值可以是null
(5)TreeSet
TreeSet可以保證元素處于排序狀態(tài),它采用紅黑樹的數(shù)據(jù)結(jié)構(gòu)來存儲(chǔ)集合元素吭敢。TreeSet支持兩種排序方法:自然排序和定制排序碰凶,默認(rèn)采用自然排序。
(6)HashMap
HashMap基于hashing原理,通過put()和get()方法存儲(chǔ)和獲取對(duì)象欲低。當(dāng)我們將鍵值對(duì)傳遞給put()方法時(shí)辕宏,它調(diào)用建對(duì)象的hashCode()方法來計(jì)算hashCode值,然后找到bucket位置來儲(chǔ)存值對(duì)象砾莱。當(dāng)獲取對(duì)象時(shí)瑞筐,通過建對(duì)象的equals()方法找到正確的鍵值對(duì),然后返回對(duì)象腊瑟。HashMap使用鏈表來解決碰撞問題聚假,當(dāng)發(fā)生碰撞了,對(duì)象將會(huì)存儲(chǔ)在鏈表的下一個(gè)節(jié)點(diǎn)中闰非。
(7)HashTable
與HashMap的關(guān)系完全類似于ArrayList與Vertor膘格,HashMap是線程不安全,HashTable是線程安全的财松,HashMap可以使用null值最為key或value瘪贱;Hashtable不允許使用null值作為key和value,如果把null放進(jìn)HashTable中辆毡,將會(huì)發(fā)生空指針異常菜秦。
(8)TreeMap
一個(gè)紅黑樹的數(shù)據(jù)結(jié)構(gòu),每個(gè)key-value對(duì)作為紅黑樹的一個(gè)節(jié)點(diǎn)舶掖。TreeMap存儲(chǔ)key-value對(duì)時(shí)喷户,需要根據(jù)key對(duì)節(jié)點(diǎn)進(jìn)行排序。
面試常問
1. ArrayList和Vector的區(qū)別访锻。
Vector:線程安全褪尝,數(shù)據(jù)增長原來的2倍。
ArrayList:非線程安全期犬,數(shù)據(jù)增長沒有明確規(guī)定河哑,從源碼來看是增長原來的1.5倍。
2. HashMap和HashTable的區(qū)別龟虎。
- 線程安全性不同:HashMap非線程安全璃谨,HashTable線程安全
- 繼承的父類不同:Hashtable繼承自Dictionary類,而HashMap繼承自AbstractMap類鲤妥。但二者都實(shí)現(xiàn)了Map接口佳吞。
- key和value是否允許null值:Hashtable中,key和value都不允許出現(xiàn)null值
- 兩個(gè)遍歷方式的內(nèi)部實(shí)現(xiàn)上不同
3. ArrayList,Vector,LinkedList的存儲(chǔ)性能和特性棉安。
ArrayList和Vector都是使用數(shù)組方式存儲(chǔ)數(shù)據(jù)底扳,此數(shù)組元素?cái)?shù)大于實(shí)際存儲(chǔ)的數(shù)據(jù)以便增加和插入元素,它們都允許直接按序號(hào)索引元素贡耽,但是插入元素要涉及數(shù)組元素移動(dòng)等內(nèi)存操作衷模,所以索引數(shù)據(jù)快而插入數(shù)據(jù)慢鹊汛,Vector由于使用了synchronized方法線程安全,性能上比ArrayList差阱冶。
而LinkedList使用雙向鏈表實(shí)現(xiàn)存儲(chǔ)刁憋,按序號(hào)索引數(shù)據(jù)需要進(jìn)行前向或后向遍歷,所以索引數(shù)據(jù)較慢木蹬,但是插入數(shù)據(jù)時(shí)只需要記錄本項(xiàng)的前后項(xiàng)即可至耻,所以插入速度較快。
4. HashMap的數(shù)據(jù)結(jié)構(gòu)镊叁。
jdk1.7:Hashmap實(shí)際上是一個(gè)數(shù)組和鏈表的散列表
jdk1.8:當(dāng)鏈表中的元素超過了 8 個(gè)以后有梆,會(huì)將鏈表轉(zhuǎn)換為紅黑樹
5. HashMap的工作原理是什么?
以鍵值對(duì)(key-value)的形式存儲(chǔ)元素的意系。HashMap需要一個(gè)hash函數(shù),它使用hashCode()和equals()方法來向集合/從集合添加和檢索元素饺汹。當(dāng)調(diào)用put()方法的時(shí)候蛔添,HashMap會(huì)計(jì)算key的hash值,然后把鍵值對(duì)存儲(chǔ)在集合中合適的索引上兜辞。如果key已經(jīng)存在了迎瞧,value會(huì)被更新成新值。HashMap的一些重要的特性是它的容量(capacity)逸吵,負(fù)載因子(loadfactor)和擴(kuò)容極限(thresholdresizing)
6. HashMap什么時(shí)候進(jìn)行擴(kuò)容呢凶硅?
當(dāng)hashmap中的元素個(gè)數(shù)超過數(shù)組大小loadFactor(加載因子)時(shí),就會(huì)進(jìn)行數(shù)組擴(kuò)容扫皱,loadFactor的默認(rèn)值為0.75足绅。
7. List、Map韩脑、Set三個(gè)接口氢妈,存取元素時(shí),各有什么特點(diǎn)段多?
List與Set具有相似性首量,它們都是單列元素的集合
Map與List和Set不同,它是雙列的集合
List表示有先后順序的集合
Set無法擁有重復(fù)元素
Map保存key-value值进苍,value可多值
8. Set里的元素是不能重復(fù)的加缘,那么用什么方法來區(qū)分重復(fù)與否呢?是用==還是equals()?它們有何區(qū)別?
Set里的元素是不能重復(fù)的,元素重復(fù)與否是使用equals()方法進(jìn)行判斷的觉啊。equals()和==方法決定引用值是否指向同一對(duì)象equals()在類中被覆蓋拣宏,為的是當(dāng)兩個(gè)分離的對(duì)象的內(nèi)容和類型相配的話,返回真值杠人。
9. 兩個(gè)對(duì)象值相同(x.equals(y)==true)蚀浆,但卻可有不同的hashcode缀程,這句話對(duì)不對(duì)?
對(duì)市俊,如果對(duì)象要保存在HashSet或HashMap中杨凑,它們的equals相等,那么摆昧,它們的hashcode值就必須相等撩满。如果不是要保存在HashSet或HashMap,則與hashcode沒有什么關(guān)系了绅你,這時(shí)候hashcode不等是可以的伺帘,例如arrayList存儲(chǔ)的對(duì)象就不用實(shí)現(xiàn)hashcode,當(dāng)然忌锯,我們沒有理由不實(shí)現(xiàn)伪嫁,通常都會(huì)去實(shí)現(xiàn)的。
10. Java集合類框架的基本接口有哪些偶垮?
Collection:代表一組對(duì)象张咳,每一個(gè)對(duì)象都是它的子元素。
Set:不包含重復(fù)元素的Collection似舵。
List:有順序的collection脚猾,并且可以包含重復(fù)元素。
Map:可以把鍵(key)映射到值(value)的對(duì)象砚哗,鍵不能重復(fù)龙助。
11. HashSet的底層實(shí)現(xiàn)是什么?
通過看源碼知道HashSet的實(shí)現(xiàn)是依賴于HashMap的蛛芥,HashSet的值都是存儲(chǔ)在HashMap中的提鸟。在HashSet的構(gòu)造法中會(huì)初始化一個(gè)HashMap對(duì)象,HashSet不允許值重復(fù)仅淑,因此沽一,HashSet的值是作為HashMap的key存儲(chǔ)在HashMap中的,當(dāng)存儲(chǔ)的值已經(jīng)存在時(shí)返回false漓糙。
12. HashSet和TreeSet有什么區(qū)別铣缠?
HashSet是由一個(gè)hash表來實(shí)現(xiàn)的,因此昆禽,它的元素是無序的蝗蛙。add(),remove()醉鳖,contains()TreeSet是由一個(gè)樹形的結(jié)構(gòu)來實(shí)現(xiàn)的捡硅,它里面的元素是有序的。因此盗棵,add()壮韭,remove()北发,contains()方法的時(shí)間復(fù)雜度是O(logn)
13. 為什么集合類沒有實(shí)現(xiàn)Cloneable和Serializable接口?
克隆(cloning)或者是序列化(serialization)的語義和含義是跟具體的實(shí)現(xiàn)相關(guān)的喷屋。因此琳拨,應(yīng)該由集合類的具體實(shí)現(xiàn)來決定如何被克隆或者是序列化。
14. 數(shù)組(Array)和列表(ArrayList)有什么區(qū)別屯曹?什么時(shí)候應(yīng)該使用Array而不是ArrayList狱庇?
Array可以包含基本類型和對(duì)象類型,ArrayList只能包含對(duì)象類型恶耽。Array大小是固定的密任,ArrayList的大小是動(dòng)態(tài)變化的。ArrayList處理固定大小的基本數(shù)據(jù)類型的時(shí)候偷俭,這種方式相對(duì)比較慢浪讳。
15. Collection和Collections的區(qū)別。
collection是集合類的上級(jí)接口,繼承與它的接口主要是set和list涌萤。collections類是針對(duì)集合類的一個(gè)幫助類.它提供一系列的靜態(tài)方法對(duì)各種集合的搜索,排序,線程安全化等操作淹遵。
16. Comparable和Comparator接口是干什么的?列出它們的區(qū)別形葬。
Java提供了只包含一個(gè)compareTo()方法的Comparable接口。這個(gè)方法可以個(gè)給兩個(gè)對(duì)象排序暮的。具體來說笙以,它返回負(fù)數(shù),0冻辩,正數(shù)來表明輸入對(duì)象小于猖腕,等于,大于已經(jīng)存在的對(duì)象恨闪。
Java提供了包含compare()和equals()兩個(gè)方法的Comparator接口倘感。compare()方法用來給兩個(gè)輸入?yún)?shù)排序,返回負(fù)數(shù)咙咽,0老玛,正數(shù)表明第一個(gè)參數(shù)是小于,等于钧敞,大于第二個(gè)參數(shù)蜡豹。equals()方法需要一個(gè)對(duì)象作為參數(shù),它用來決定輸入?yún)?shù)是否和comparator相等溉苛。只有當(dāng)輸入?yún)?shù)也是一個(gè)comparator并且輸入?yún)?shù)和當(dāng)前comparator的排序結(jié)果是相同的時(shí)候镜廉,這個(gè)方法才返回true。
總結(jié):
學(xué)無止境愚战,學(xué)習(xí)是一種態(tài)度娇唯,無論你是小白菜鳥齐遵,還是技術(shù)大牛,日常都不能夠落下學(xué)習(xí)這件事情塔插,一旦落后下來梗摇,就容易遭到淘汰。
以上就是我的經(jīng)歷分享佑淀,和資料整理留美,全部都已打包好,均是免費(fèi)分享的伸刃,等待愛學(xué)習(xí)的你谎砾,需要這些資料的朋友可以私信我哦