經(jīng)典Java面試題的答案——容器

大家好,我是九神。這是互聯(lián)網(wǎng)技術(shù)崗的分享專題,廢話少說,進(jìn)入正題:

18.Java 容器都有哪些?

Java主要包括兩種類型的容器,一種是Collection,存儲(chǔ)一列元素,另一種是Map,存儲(chǔ)鍵/值對(duì)映射。Collection接口又有3種子類型,List、Set和Queue。

19.Collection 和 Collections 有什么區(qū)別?

java.util.Collection 是一個(gè)集合接口(集合類的一個(gè)頂級(jí)接口)。它提供了對(duì)集合對(duì)象進(jìn)行基本操作的通用接口方法。Collection接口在Java 類庫中有很多具體的實(shí)現(xiàn)。Collection接口的意義是為各種具體的集合提供了最大化的統(tǒng)一操作方式,其直接繼承接口有List與Set。

java.util.Collections則是集合類的一個(gè)工具類/幫助類,其中提供了一系列靜態(tài)方法,用于對(duì)集合中元素進(jìn)行排序、搜索以及線程安全等各種操作。此類不能實(shí)例化。

20.List、Set、Map 之間的區(qū)別是什么?

img

21.HashMap 和 Hashtable 有什么區(qū)別?

hashMap去掉了HashTable 的contains方法,但是加上了containsValue()和containsKey()方法。

hashTable同步的,而HashMap是非同步的,效率上逼hashTable要高。

hashMap允許空鍵值,而hashTable不允許。

22.如何決定使用 HashMap 還是 TreeMap?

如果你需要得到一個(gè)有序的結(jié)果時(shí)就應(yīng)該使用TreeMap(因?yàn)镠ashMap中元素的排列順序是不固定的)。除此之外,由于HashMap有更好的性能,所以大多不需要排序的時(shí)候我們會(huì)使用HashMap。

原因:

TreeMap<K,V>的Key值是要求實(shí)現(xiàn)java.lang.Comparable,所以迭代的時(shí)候TreeMap默認(rèn)是按照Key值升序排序的;TreeMap的實(shí)現(xiàn)是基于紅黑樹結(jié)構(gòu)。適用于按自然順序或自定義順序遍歷鍵(key)。

HashMap<K,V>的Key值實(shí)現(xiàn)散列hashCode(),分布是散列的、均勻的,不支持排序;數(shù)據(jù)結(jié)構(gòu)主要是桶(數(shù)組),鏈表或紅黑樹。適用于在Map中插入、刪除和定位元素。

23.說一下 HashMap 的實(shí)現(xiàn)原理?

  • HashMap 基于 Hash 算法實(shí)現(xiàn),通過 put(key,value) 存儲(chǔ),get(key) 來獲取 value

  • 當(dāng)傳入 key 時(shí),HashMap 會(huì)根據(jù) key,調(diào)用 hash(Object key) 方法,計(jì)算出 hash 值,根據(jù) hash 值將 value 保存在 Node 對(duì)象里,Node 對(duì)象保存在數(shù)組里

  • 當(dāng)計(jì)算出的 hash 值相同時(shí),稱之為 hash 沖突,HashMap 的做法是用鏈表和紅黑樹存儲(chǔ)相同 hash 值的 value

  • 當(dāng) hash 沖突的個(gè)數(shù):小于等于 8 使用鏈表;大于 8 時(shí),使用紅黑樹解決鏈表查詢慢的問題

這個(gè)問題答到這里OK了,但是你需要理解:不是每個(gè)java版本里,hashMap的實(shí)現(xiàn)原理都是不變的,醬油君告訴你,java不同的版本在這個(gè)如何獲取key的hash值和減少hash值沖突的問題上在不斷的優(yōu)化。

24.說一下 HashSet 的實(shí)現(xiàn)原理?

HashSet是基于HashMap實(shí)現(xiàn)的,HashSet中的元素都存放在HashMap的key上面,而value中的值都是統(tǒng)一的一個(gè)private static final Object PRESENT = new Object()。

25.ArrayList 和 LinkedList 的區(qū)別是什么?

  • ArrayList是實(shí)現(xiàn)了基于動(dòng)態(tài)數(shù)組的數(shù)據(jù)結(jié)構(gòu),LinkedList是基于鏈表結(jié)構(gòu)。

  • 對(duì)于隨機(jī)訪問的get和set方法,ArrayList要優(yōu)于LinkedList,因?yàn)長inkedList要移動(dòng)指針。

  • 對(duì)于新增和刪除操作add和remove,LinkedList比較占優(yōu)勢(shì),因?yàn)锳rrayList要移動(dòng)數(shù)據(jù)。

26.如何實(shí)現(xiàn)數(shù)組和 List 之間的轉(zhuǎn)換?

List轉(zhuǎn)換成為數(shù)組:調(diào)用ArrayList的toArray方法。

數(shù)組轉(zhuǎn)換成為List:調(diào)用Arrays的asList方法。

27.ArrayList 和 Vector 的區(qū)別是什么?

線程安全:Vector 使用了 Synchronized 來實(shí)現(xiàn)線程同步,是線程安全的,而 ArrayList 是非線程安全的。

性能:ArrayList 在性能方面要優(yōu)于 Vector。原因就是Vector是線程安全的,即某一時(shí)刻只有一個(gè)線程能夠?qū)慥ector,避免多線程同時(shí)寫而引起的不一致性,但實(shí)現(xiàn)同步需要很高的花費(fèi)。

擴(kuò)容:ArrayList 和 Vector 都會(huì)根據(jù)實(shí)際的需要?jiǎng)討B(tài)的調(diào)整容量, 只不過在 Vector 擴(kuò)容每次會(huì)增加 1 倍,而 ArrayList 只會(huì)增加 50%。

28.Array 和 ArrayList 有何區(qū)別?

  • Array可以容納基本類型和對(duì)象,而ArrayList只能容納對(duì)象。

  • Array是指定大小的,而ArrayList大小是固定的。

  • Array沒有提供ArrayList那么多功能,比如addAll、removeAll和iterator等。

29.在 Queue 中 poll()和 remove()有什么區(qū)別?

相同點(diǎn):都是返回第一個(gè)元素,并在隊(duì)列中刪除返回的對(duì)象。

不同點(diǎn):如果沒有元素 poll()會(huì)返回 null,而 remove()會(huì)直接拋出 NoSuchElementException 異常。

30.哪些集合類是線程安全的?

  • vector:就比arraylist多了個(gè)同步化機(jī)制(線程安全),因?yàn)樾瘦^低,現(xiàn)在已經(jīng)不太建議使用。在web應(yīng)用中,特別是前臺(tái)頁面,往往效率(頁面響應(yīng)速度)是優(yōu)先考慮的。

  • statck:堆棧類,先進(jìn)后出。

  • hashtable:就比hashmap多了個(gè)線程安全。

  • enumeration:枚舉,相當(dāng)于迭代器。

31.迭代器 Iterator 是什么?

迭代器是一種設(shè)計(jì)模式,它是一個(gè)對(duì)象,它可以遍歷并選擇序列中的對(duì)象,而開發(fā)人員不需要了解該序列的底層結(jié)構(gòu)。迭代器通常被稱為“輕量級(jí)”對(duì)象,因?yàn)閯?chuàng)建它的代價(jià)小。

32.Iterator 怎么使用?有什么特點(diǎn)?

Iterator怎么使用?

  • Iterator()要求容器返回一個(gè)Iterator。Iterator將準(zhǔn)備好返回序列的第一個(gè)元素。

  • 使用next()獲得序列中的下一個(gè)元素

  • 使用hasNext()檢查序列中是否還有元素。

  • 使用remove()將迭代器新近返回的元素刪除。

Iterator的特點(diǎn)?

  • Iterator遍歷集合元素的過程中不允許線程對(duì)集合元素進(jìn)行修改,否則會(huì)拋出ConcurrentModificationEception的異常。

  • Iterator必須依附于一個(gè)集合類對(duì)象而存在,Iterator本身不具有裝載數(shù)據(jù)對(duì)象的功能。

33.Iterator 和 ListIterator 有什么區(qū)別?

  • Iterator可用來遍歷Set和List集合,但是ListIterator只能用來遍歷List。

  • Iterator對(duì)集合只能是前向遍歷,ListIterator既可以前向也可以后向。

  • ListIterator實(shí)現(xiàn)了Iterator接口,并包含其他的功能,比如:增加元素,替換元素,獲取前一個(gè)和后一個(gè)元素的索引,等等。

34.怎么確保一個(gè)集合不能被修改?

可以使用 Collections. unmodifiableCollection(Collection c) 方法來創(chuàng)建一個(gè)只讀集合,這樣改變集合的任何操作都會(huì)拋出 Java. lang. UnsupportedOperationException 異常。

舉例:

List<String> list = new ArrayList<>();
list.add("A");
Collection<String> unmlist = Collections. unmodifiableCollection(list);
unmlist.add("B"); // 運(yùn)行時(shí)此行報(bào)錯(cuò)
System. out. println(list.size());

文章轉(zhuǎn)載自:
經(jīng)典Java面試題的答案——容器

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容