21個(gè)Java Collections面試問答

Java Collections框架是Java編程語言的核心API之一肛走。

這是Java面試問題的重要主題之一。在這里,我列出了一些重要的Java集合面試問題和解答州弟,以幫助您進(jìn)行面試。這直接來自我14年以上的Java編程經(jīng)驗(yàn)。

1婆翔、Java 8中與Collections相關(guān)的功能是什么拯杠?

Java 8對 Collection API 進(jìn)行了重大更改。一些更改是:

  1. Java Stream API 用于集合類啃奴,以支持順序處理和并行處理
  2. Iterable 接口中的默認(rèn)方法forEach()潭陪,可用于迭代集合。與 lambda 表達(dá)式一起使用時(shí)最蕾,它非常有用依溯,因?yàn)槠鋮?shù) Consumer 是函數(shù)接口。
  3. Collections API 改進(jìn)瘟则,如在Iterator接口中的forEachRemaining(Consumer action)黎炉,MapreplaceAll()compute()壹粟,merge()方法拜隧。

2、什么是 Java Collections Framework趁仙?列出 Collections 框架的一些好處洪添?

每個(gè)編程語言都使用集合,和最初的Java版本包含幾個(gè)集合類:Vector雀费,Stack干奢,HashtableArray。但是從較高的范圍和用法來看盏袄,Java 1.2提出了Collections Framework忿峻,該框架將所有collections接口,實(shí)現(xiàn)和算法分組辕羽。

Java的集合通過使用泛型和并發(fā)集合類進(jìn)行線程安全操作已經(jīng)走了很長一段路逛尚。它還包括在Java的并發(fā)包中的阻塞接口及其實(shí)現(xiàn)。

Collections 框架的一些好處是刁愿;

  • 通過使用核心集合類而不是實(shí)現(xiàn)我們自己的集合類來減少開發(fā)工作绰寞。
  • 通過使用通過良好測試的集合框架類,可以提高代碼質(zhì)量铣口。
  • 通過使用JDK附帶的集合類滤钱,減少了代碼維護(hù)工作。
  • 可重用性和互操作性

3脑题、集合框架中泛型的好處是什么件缸?

Java 1.5帶有泛型,所有集合接口和實(shí)現(xiàn)都大量使用它叔遂。泛型允許我們提供集合可以包含的Object的類型他炊,因此争剿,如果您嘗試添加其他類型的任何元素,則引發(fā)編譯時(shí)錯(cuò)誤佑稠。

這樣可以避免在運(yùn)行時(shí)發(fā)生ClassCastException秒梅,因?yàn)槟鷮⒃诰幾g時(shí)收到錯(cuò)誤。由于我們不需要使用強(qiáng)制轉(zhuǎn)換和實(shí)例化運(yùn)算符舌胶,因此泛型也使代碼更干凈捆蜀。

4、Java Collections Framework的基本接口是什么幔嫂?

Collection 表示集合層次結(jié)構(gòu)的根辆它。Collection表示一組元素的對象。Java平臺(tái)不提供此接口的任何直接實(shí)現(xiàn)履恩。

Set是一個(gè)不能包含重復(fù)元素的集合锰茉。此接口對數(shù)學(xué)集合的抽象進(jìn)行建模,并表示集合切心,例如紙牌集合垂券。

List是一個(gè)有序的集合趾代,可以包含重復(fù)的元素。您可以從其索引訪問任何元素。該列表更像是具有動(dòng)態(tài)長度的數(shù)組届囚。

一個(gè)Map是鍵映射到值的對象缩宜。映射不能包含重復(fù)的鍵:每個(gè)鍵最多可以映射到一個(gè)值的猛。

其他一些接口Queue安皱,DequeueIterator认然,SortedSet补憾,SortedMapListIterator

5卷员、為什么Collection不實(shí)現(xiàn)Cloneable和Serializable接口盈匾?

Collection接口指定為一組元素對象。元素的維護(hù)方式取決于Collection的具體實(shí)現(xiàn)毕骡。例如威酒,某些Collection實(shí)現(xiàn)(例如List)允許重復(fù)元素,而其他實(shí)現(xiàn)(例如Set)則不允許重復(fù)元素挺峡。

許多Collection實(shí)現(xiàn)都有Cloneable方法。但是担钮,將其包含在Collection的所有實(shí)現(xiàn)中沒有意義橱赠。這是因?yàn)镃ollection是抽象表示。重要的是箫津。
在處理實(shí)際實(shí)現(xiàn)時(shí)狭姨,克隆或序列化的語義及其含義都會(huì)發(fā)揮作用宰啦。因此具體的實(shí)現(xiàn)應(yīng)決定如何克隆或序列化它,甚至可以對其進(jìn)行克隆或序列化饼拍。
因此赡模,在所有實(shí)現(xiàn)中強(qiáng)制進(jìn)行克隆和序列化的靈活性較差,限制也更大师抄。具體實(shí)現(xiàn)應(yīng)決定是否可以克隆或序列化漓柑。

6、為什么Map接口沒有實(shí)現(xiàn)Collection接口叨吮?

盡管Map接口及其實(shí)現(xiàn)是Collections Framework的一部分辆布,但Map不是集合,集合也不是Map茶鉴。因此锋玲,Map擴(kuò)展Collection是沒有意義的,反之亦然涵叮。

如果Map擴(kuò)展了Collection接口惭蹂,那么元素在哪里?該映射包含key-value對割粮,并且提供了一些方法來檢索鍵或值的列表作為Collection盾碗,但它不適合“元素組”范式。

7穆刻、什么是迭代器置尔?

迭代器接口提供了對任何Collection進(jìn)行迭代的方法。我們可以使用iterator()方法從Collection中獲取迭代器實(shí)例氢伟。在Java Collections Framework中榜轿,迭代器代替了枚舉。迭代器允許調(diào)用者在迭代過程中從基礎(chǔ)集合中刪除元素朵锣。Java Collection迭代器提供了遍歷集合元素的通用方法谬盐,并實(shí)現(xiàn)了Iterator Design Pattern

8诚些、Enumeration和Iterator接口之間有什么區(qū)別飞傀?

枚舉的速度是Iterator的兩倍,并且使用的內(nèi)存更少诬烹。枚舉是非吃曳常基本的,適合基本需求绞吁。但是幢痘,與Enumeration相比,Iterator安全得多家破,因?yàn)樗冀K拒絕其他線程修改被其迭代的集合對象颜说。

在Java Collections Framework中购岗,迭代器代替了枚舉。迭代器允許調(diào)用者從基礎(chǔ)集合中刪除Enumeration無法實(shí)現(xiàn)的元素门粪。迭代器方法名稱已得到改進(jìn)喊积,以使其功能更清晰。

9玄妈、為什么沒有像Iterator.add()這樣的方法將元素添加到集合中乾吻?

考慮到Iterator的約定不保證迭代順序,原因尚不清楚措近。但是請注意溶弟,ListIterator確實(shí)提供了add操作,因?yàn)樗_實(shí)保證了迭代的順序瞭郑。

10辜御、為什么Iterator沒有不移動(dòng)光標(biāo)就直接獲取下一個(gè)元素的方法?

可以在當(dāng)前Iterator接口的頂部實(shí)現(xiàn)它屈张,但是由于很少使用它擒权,因此將它包含在每個(gè)人都必須實(shí)現(xiàn)的接口中沒有意義。

11阁谆、Iterator和ListIterator有什么區(qū)別碳抄?

  • 我們可以使用Iterator遍歷Set和List集合,而ListIterator只能與Lists一起使用场绿。
  • Iterator只能向前移動(dòng)剖效,而ListIterator可以用于兩個(gè)方向。
  • ListIterator繼承自Iterator接口焰盗,并具有其他功能璧尸,例如添加元素,替換元素熬拒,獲取上一個(gè)和下一個(gè)元素的索引位置爷光。

12、有哪些不同的方法可以遍歷列表澎粟?

我們可以通過兩種不同的方式遍歷列表-使用迭代器和使用for-each循環(huán)蛀序。

List <String> strList = new ArrayList<>();

for(String obj:strList){
    System.out.println(obj);
}

Iterator<String> it= strList.iterator();
while(it.hasNext()){
    String obj = it.next();
    System.out.println(obj);
}

使用迭代器更加線程安全,因?yàn)樗梢源_保如果基礎(chǔ)列表元素被修改活烙,它將拋出異常ConcurrentModificationException徐裸。

13、您對Iterator fail-fast屬性有什么了解啸盏?

每當(dāng)我們嘗試獲取下一個(gè)元素時(shí)重贺,迭代器fail-fast屬性都會(huì)檢查基礎(chǔ)集合的結(jié)構(gòu)是否有任何修改。如果找到任何修改,則拋出ConcurrentModificationException檬姥。除了并行并發(fā)類(例如ConcurrentHashMap和CopyOnWriteArrayList)之外,Collection類中Iterator的所有實(shí)現(xiàn)在設(shè)計(jì)上都是fail-fast的粉怕。

14健民、fail-fast和fail-safe之間有何區(qū)別?

Iterato fail-safe屬性可與基礎(chǔ)集合的克隆一起使用贫贝,因此不受集合中任何修改的影響秉犹。按照設(shè)計(jì),java.util包中的所有集合類都是fail-fast的稚晚,而其中的集合類java.util.concurrent是fail-safe的崇堵。
fail-fast迭代器會(huì)拋出ConcurrentModificationException,而fail-safe迭代器絕不會(huì)拋出ConcurrentModificationException客燕。

15鸳劳、如何在迭代集合時(shí)避免ConcurrentModificationException?

我們可以使用并發(fā)集合類來避免ConcurrentModificationException在集合上進(jìn)行迭代也搓,例如使用CopyOnWriteArrayList而不是ArrayList赏廓。

16、為什么沒有Iterator接口的具體實(shí)現(xiàn)傍妒?

Iterator接口聲明了用于迭代集合的方法幔摸,但是其實(shí)現(xiàn)是Collection實(shí)現(xiàn)類的責(zé)任。每個(gè)返回迭代器以進(jìn)行遍歷的集合類都有其自己的Iterator實(shí)現(xiàn)嵌套類颤练。

這使集合類可以選擇迭代器是fail-fast還是fail-safe的既忆。例如,ArrayList迭代器是fail-fast的嗦玖,而CopyOnWriteArrayList迭代器是fail-safe的患雇。

17、什么是UnsupportedOperationException踏揣?

UnsupportedOperationException是用于指示不支持該操作的異常庆亡。它廣泛用于在JDK類,在集合框架java.util.Collections.UnmodifiableCollection拋出該異常所有addremove操作捞稿。

18又谋、HashMap如何在Java中工作?

HashMap在Map.Entry靜態(tài)嵌套類實(shí)現(xiàn)中存儲(chǔ)鍵值對娱局。HashMap使用哈希算法彰亥,并在putget方法中使用hashCode()和equals()方法。

當(dāng)我們put通過傳遞鍵值對來調(diào)用方法時(shí)衰齐,HashMap使用帶有哈希值的Key hashCode()來查找存儲(chǔ)鍵值對的索引任斋。該條目存儲(chǔ)在LinkedList中,因此耻涛,如果已經(jīng)存在一個(gè)條目废酷,則使用equals()方法檢查傳遞的鍵是否已存在瘟檩,如果是,它將覆蓋該值澈蟆,否則它將創(chuàng)建一個(gè)新條目并存儲(chǔ)此鍵值條目墨辛。

當(dāng)我們get通過傳遞Key來調(diào)用method時(shí),它再次使用hashCode()在數(shù)組中找到索引趴俘,然后使用equals()方法找到正確的Entry并返回其值睹簇。下圖將清楚地解釋這些細(xì)節(jié)。

image

有關(guān)HashMap的其他重要信息是容量寥闪,負(fù)載因子太惠,閾值大小調(diào)整。HashMap的初始默認(rèn)容量為16疲憋,負(fù)載系數(shù)為0.75凿渊。閾值是容量乘以負(fù)載因子,并且如果Map大小大于閾值柜某,則每當(dāng)我們嘗試添加條目時(shí)嗽元,HashMap都會(huì)將Map的內(nèi)容重新映射為容量更大的新數(shù)組。容量始終是2的乘方喂击,因此剂癌,如果您知道需要存儲(chǔ)大量的鍵值對,例如在緩存數(shù)據(jù)庫中的數(shù)據(jù)時(shí)翰绊,最好使用正確的容量和負(fù)載因子來初始化HashMap佩谷。 。

19监嗜、hashCode()和equals()方法的重要性是什么谐檀?

HashMap使用Key對象的hashCode()和equals()方法來確定放置鍵值對的索引。當(dāng)我們嘗試從HashMap中獲取價(jià)值時(shí)裁奇,也會(huì)使用這些方法桐猬。如果這些方法的實(shí)現(xiàn)不正確,則兩個(gè)不同的Key可能會(huì)產(chǎn)生相同的hashCode()和equals()輸出刽肠,在這種情況下溃肪,HashMap不會(huì)考慮將它們存儲(chǔ)在不同的位置,而是將其覆蓋并覆蓋它們音五。

同樣惫撰,所有不存儲(chǔ)重復(fù)數(shù)據(jù)的集合類都使用hashCode()和equals()查找重復(fù)項(xiàng),因此正確實(shí)現(xiàn)它們非常重要躺涝。equals()和hashCode()的實(shí)現(xiàn)應(yīng)遵循以下規(guī)則厨钻。

  • 如果o1.equals(o2),那么o1.hashCode() == o2.hashCode()應(yīng)該永遠(yuǎn)如此true
  • 如果o1.hashCode() == o2.hashCode是真的夯膀,這并不意味著o1.equals(o2)會(huì)true诗充。

20、我們可以使用任何類作為Map鍵嗎诱建?

我們可以將任何類用作Map Key其障,但是在使用它們之前應(yīng)考慮以下幾點(diǎn)。

  • 如果該類重寫equals()方法涂佃,則它也應(yīng)該重寫hashCode()方法。

  • 對于所有實(shí)例蜈敢,該類應(yīng)遵循與equals()和hashCode()關(guān)聯(lián)的規(guī)則辜荠。這些規(guī)則請參考前面的問題。

  • 如果equals()中未使用類字段抓狭,則不應(yīng)在hashCode()方法中使用它伯病。

  • 用戶定義的鍵類的最佳實(shí)踐是使其不可變,以便可以將hashCode()值緩存起來以提高性能否过。不可變的類還確保hashCode()和equals()將來不會(huì)更改午笛,這將解決任何可變性問題。
    例如苗桂,假設(shè)我有一個(gè)MyKey用于HashMap鍵的類药磺。

    //傳遞的mykey name參數(shù)用于equals()和hashcode()
    MyKey key = new MyKey("Pankaj"); //假定hashCode=1234
    myHashMap.put(key, "Value");
    
    // 下面的代碼將更改equals()和hashcode()的key
    // 但是它的位置不會(huì)改變
    key.setName("Amit"); //假定新的hashCode=7890
    
    //下面將返回null,因?yàn)镠ashMap將嘗試查找鍵
    //與存儲(chǔ)在同一索引中煤伟,但由于密鑰發(fā)生了變化癌佩,
    //不匹配,返回空便锨。
    myHashMap.get(new MyKey("Pankaj")); 
    

    這就是為什么String和Integer大多用作HashMap鍵的原因围辙。

21、Map接口提供哪些不同的Collection視圖放案?

Map接口提供了三個(gè)集合視圖:

  1. Set <K> keySet():返回此映射中包含的鍵的Set視圖姚建。該集合由Map支持,因此對Map的更改會(huì)反映在集合中吱殉,反之亦然掸冤。如果在對集合進(jìn)行迭代時(shí)修改了映射(通過迭代器的remove操作除外),則迭代的結(jié)果不確定考婴。該集合支持元素刪除贩虾,該元素通過迭代器remove,Set.remove沥阱,removeAll缎罢,retainAll和clear操作從映射中刪除相應(yīng)的映射。它不支持add或addAll操作。
  2. Collection <V> values():返回此映射中包含的值的Collection視圖策精。集合由Map支持舰始,因此對Map的更改會(huì)反映在集合中,反之亦然咽袜。如果在對集合進(jìn)行迭代時(shí)修改了映射(通過迭代器的remove操作除外)丸卷,則迭代結(jié)果不確定。集合支持元素刪除询刹,該元素通過迭代器remove谜嫉,Collection.remove,removeAll凹联,retainAll和clear操作從映射中刪除相應(yīng)的映射沐兰。它不支持add或addAll操作。
  3. Set <Map.Entry <K蔽挠,V >> entrySet():返回此映射中包含的映射的Set視圖住闯。該集合由Map支持,因此對Map的更改會(huì)反映在集合中澳淑,反之亦然比原。如果在對集合進(jìn)行迭代時(shí)修改了映射(通過迭代器的remove操作或迭代器返回的映射條目上的setValue操作除外),則迭代的結(jié)果不確定杠巡。該集合支持元素刪除量窘,該元素通過迭代器remove,Set.remove氢拥,removeAll绑改,retainAll和clear操作從映射中刪除相應(yīng)的映射。它不支持add或addAll操作兄一。

“不積跬步厘线,無以至千里”,希望未來的你能:有夢為馬 隨處可棲出革!加油造壮,少年!

關(guān)注公眾號(hào):「Java 知己」骂束,每天更新Java知識(shí)哦耳璧,期待你的到來!

  • 發(fā)送「Group」展箱,與 10 萬程序員一起進(jìn)步旨枯。
  • 發(fā)送「面試」,領(lǐng)取BATJ面試資料混驰、面試視頻攻略攀隔。
  • 發(fā)送「玩轉(zhuǎn)算法」皂贩,領(lǐng)取《玩轉(zhuǎn)算法》系列視頻教程。
  • 千萬不要發(fā)送「1024」...
每日福利
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末昆汹,一起剝皮案震驚了整個(gè)濱河市明刷,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌满粗,老刑警劉巖辈末,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異映皆,居然都是意外死亡挤聘,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進(jìn)店門捅彻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來檬洞,“玉大人,你說我怎么就攤上這事沟饥。” “怎么了湾戳?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵贤旷,是天一觀的道長。 經(jīng)常有香客問我砾脑,道長幼驶,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任韧衣,我火速辦了婚禮盅藻,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘畅铭。我一直安慰自己氏淑,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布硕噩。 她就那樣靜靜地躺著假残,像睡著了一般。 火紅的嫁衣襯著肌膚如雪炉擅。 梳的紋絲不亂的頭發(fā)上辉懒,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天,我揣著相機(jī)與錄音谍失,去河邊找鬼眶俩。 笑死,一個(gè)胖子當(dāng)著我的面吹牛快鱼,可吹牛的內(nèi)容都是我干的颠印。 我是一名探鬼主播纲岭,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼嗽仪!你這毒婦竟也來了荒勇?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤闻坚,失蹤者是張志新(化名)和其女友劉穎沽翔,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體窿凤,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡仅偎,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了雳殊。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片橘沥。...
    茶點(diǎn)故事閱讀 40,090評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖夯秃,靈堂內(nèi)的尸體忽然破棺而出座咆,到底是詐尸還是另有隱情,我是刑警寧澤仓洼,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布介陶,位于F島的核電站,受9級(jí)特大地震影響色建,放射性物質(zhì)發(fā)生泄漏哺呜。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一箕戳、第九天 我趴在偏房一處隱蔽的房頂上張望某残。 院中可真熱鬧,春花似錦陵吸、人聲如沸玻墅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽椭豫。三九已至,卻和暖如春旨指,著一層夾襖步出監(jiān)牢的瞬間赏酥,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工谆构, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留裸扶,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓搬素,卻偏偏與公主長得像呵晨,于是被迫代替她去往敵國和親魏保。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評論 2 355

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